2016-06-14 33 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',那麼您將在註釋中看到它只會讀取一個觀察值。這是我不明白的。 –

相關問題