2016-06-14 6 views
1

Ich versuche, ein Programm zu erstellen, das eine Textdatei übernimmt, alle darin enthaltenen Makroverweise ersetzt und sie an eine einzige Ausgabedatei anfügt. Die Makroreferenzen werden generiert, wenn ich über die Beobachtungen in einem Datensatz iteriere.Eine Datei Zeile für Zeile für jede Beobachtung in einem Dataset lesen

Ich habe Probleme, es zu versuchen, die gesamte Textdatei für jede Beobachtung in meiner Quellentabelle zu lesen. Ich denke, es gibt eine implizite stop Anweisung im Zusammenhang mit meiner Verwendung der end= Option auf der infile-Anweisung, die verhindert, dass meine Set-Anweisung über jeden Datensatz iterieren.

ich die Vorlage und Code vereinfacht haben, Beispiele unter:

Hier ist die Vorlage, die ich zu füllen bin versucht:

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

Hier ist der SAS Code:

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; 

Das Ausführen des obigen Codes erzeugt die gewünschte Ausgabedatei, aber nur für die erste Beobachtung im Dataset.

Antwort

2

Dies ist nicht möglich, da Sie sich nach der ersten Beobachtung bereits am Ende der Eingabetextdatei befinden. So läuft Ihre DO WHILE Schleife nur für die erste Beobachtung.

Hier ist ein Trick, den ich vor langer Zeit auf SAS-L gelernt habe. Wechseln Sie zwischen zwei Eingabedateien, sodass Sie erneut am Anfang der Eingabedatei beginnen können.

Zuerst erstellen wir Ihr Beispielvorlagenprogramm und eine leere Dummy-Datei.

filename template temp; 
filename dummy temp; 

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

Lassen Sie uns nun einen Daten Schritt schreiben, um die Eingangsdaten zu lesen und RESOLVE() Funktion, um den Text zu konvertieren.

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; 

Die resultierende Datei wird wie folgt aussehen:

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

Vielen Dank für dieses konnte ich es zum Laufen bringen. Kannst du erklären, warum mein ursprünglicher Versuch nicht funktioniert? Ich möchte mein Verständnis verbessern ... –

+0

Sie lesen die vollständige Eingabetextdatei bei der ersten Iteration des Datenschritts. Dann gab es keine Möglichkeit, SAS mitzuteilen, dass es die Textdatei von Anfang an lesen sollte, wenn Sie zur nächsten Beobachtung des Datenschritts kamen. Wenn Sie die Option FILEVAR verwenden, wird die Eingabetextdatei geschlossen und erneut geöffnet, wenn sich der Wert des Dateinamens ändert. – Tom

+0

Ah, tut mir leid, ich musste in meinem vorherigen Kommentar klarer sein. Die Sache, die mich verwirrte, war, dass mein Code tatsächlich die Bearbeitung meines Datensatzes nach der Beobachtung 1 beendet! Wenn ich meine Anweisung 'data _null_' in' data tmp' ändere, dann sehen Sie in den Notizen nur eine einzige Beobachtung. Das verstehe ich nicht. –