2016-06-14 72 views
1

我试图创建一个程序,它接受一个文本文件,替换其中的任何宏引用,并将其附加到单个输出文件。在我遍历数据集中的观察值时生成宏引用。为数据集中的每个观察项逐行读取一个文件

我在尝试让它读取源表中每个观察值的整个文本文件时遇到了问题。我认为有一个隐含的stop指令涉及我在infile语句中使用end=选项,它阻止了我的set语句迭代每条记录。

我已经简化模板和代码,下面的例子:

这里是我想要填充模板:

INSERT INTO some_table (name,age)  
VALUES (&name,&age); 

下面是SAS代码:

filename dest "%sysfunc(pathname(work))\backfill.sql"; 

data _null_; 
    attrib line length=$1000; 

    set sashelp.class; 

    file dest; 
    infile "sql_template.sas" end=template_eof; 

    call symput('name', quote(cats(name))); 
    call symput('age' , cats(age)); 

    do while (not template_eof); 
    input; 
    line = resolve(_infile_); 
    put line; 
    end; 
run; 

运行上面的代码会生成所需的输出文件,但仅适用于数据集中的第一个观测值。

回答

2

你不能这样做,因为在第一次观察之后,你已经在输入文本文件的末尾。所以你的DO WHILE循环只运行第一次观察。

这是我很久以前在SAS-L学到的一个技巧。在两个输入文件之间切换,以便您可以再次从输入文件的顶部开始。

首先让我们创建您的示例模板程序和一个空的虚拟文件。

filename template temp; 
filename dummy temp; 

data _null_; 
    file template; 
    put 'INSERT INTO some_table (name,age)' 
    /' VALUES (&name,&age)' 
    /';' 
    ; 
    file dummy ; 
run; 

现在让我们写一个数据步来读取输入数据,并使用RESOLVE()功能将文本转换。

filename result temp; 

data _null_; 
    length filename $256 ; 
    file result ; 
    set sashelp.class; 
    call symputx('name', catq('1at',name)); 
    call symputx('age' , age); 

    do filename=pathname('template'),pathname('dummy'); 
    infile in filevar=filename end=eof ; 
    do while (not eof); 
     input; 
     _infile_ = resolve(_infile_); 
     put _infile_; 
    end; 
    end; 
run; 

产生的文件将是这样的:

INSERT INTO some_table (name,age) 
    VALUES ('Alfred',14) 
; 
INSERT INTO some_table (name,age) 
    VALUES ('Alice',13) 
; 
... 
+0

感谢这个我能得到它的工作。你能解释为什么我原来的尝试不起作用吗?我想提高我的理解... –

+0

您在数据步骤的第一次迭代中读取完整的输入文本文件。然后无法告诉SAS从开始时开始阅读文本文件,当您进入数据步骤的下一个观察点时。通过使用FILEVAR选项,它将在文件名的值更改时关闭并重新打开输入文本文件。 – Tom

+0

啊,对不起,我需要在我之前的评论中更清楚。让我感到困惑的是,我的代码实际上在观察1后停止处理我的数据集!如果我将'data _null_'语句更改为'data tmp',那么您将在注释中看到它只会读取一个观察值。这是我不明白的。 –

相关问题