2014-01-23 48 views
3

我在SAS中很少有經驗。我有SQL方面的經驗。從文件運行SQL語句以創建SAS中的數據

我想要執行以下操作: - 使用存儲在文本文件中的SQL語句將數據導入SAS。

複製和粘貼SQL服務器查詢並將其作爲SAS中的傳遞查詢運行它的作用是什麼。我得到的數據(幾分鐘後)。

但我希望能夠管理和開發SSMS中的SQL腳本,並將腳本存儲在一個sql文件中。所以,我試過如下:

proc sql; 
connect to ODBC("dsn=DatabaseOfInterest"); 
create table NewDataSet as select * from connection to odbc(
%include 'C:\sqlscript.sql'; 
); 
quit ; 

這不工作,並創建了以下錯誤:

**ERROR: CLI prepare error: 
[Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near '%'. 
** 

有沒有辦法來實現這一目標?

+0

你可以發佈一個SQL腳本的樣本嗎? – 2014-01-23 16:32:58

回答

3

我不知道是否有一個真正乾淨的方法來解決這個問題。問題是,連接到SQL將%include傳遞給SQL解析器,這與您打算的相比當然不正確。

但是,它會正確解析宏和宏變量,因此您可以將SQL命令讀入宏變量並以此方式使用它。下面是一種方法。

filename tempfile temp; *imaginary file - this would be your SQL script; 
data _null_;    *creating a mocked up SQL script file; 
file tempfile; 
put "select * from country"; 
run; 

data _null_;    *reading the SQL script into a variable, hopefully under 32767?; 
infile tempfile recfm=f lrecl=32767 pad; 
input @1 sqlcode $32767.; 
call symputx('sqlcode',sqlcode); *putting it into a macro variable; 
run; 


proc sql;    *using it; 
connect to oledb(init_string=&dev_string); 
select * from connection to oledb(
&sqlcode. 
); 
quit; 
+0

非常感謝。我複製了你的代碼。相反 'INFILE tempfile' 我用 'INFILE 「NetworkPath \ File.sql」' 我只是不知道32767名是什麼意思。 – Wietze314

+0

@Wietze 32767只是說文件中的行最長可達32767個字符。這是SAS允許的最大長度。因此,在文件中沒有任何行超過列32767,否則SAS將截斷行。 –

+2

技術說明(@RobPenridge):SAS確實允許LRECL大於32767(達到系統最大值,對於至少爲100萬個字符的窗口)。但是,它不允許字符變量大於此值,所以我的解決方案不適用於更大的文件,也不會有任何基於_INFILE_的解決方案,所以Rob的建議基本上是正確的。 – Joe

1

包含您的SQL代碼的文件是C:\sqlscript.sql。我會認爲它看起來是這樣的:

select * from mytable; 

編輯的文件,以便它現在看起來是這樣......

%macro sqlscript; 
    select * from mytable; 
%mend; 

...然後將文件擴展名重命名爲C:\sqlscript.sas

最後,改變你的proc sql代碼看起來像這樣:

options sasautos = ("c:\", sasautos); 

proc sql; 
    connect to ODBC("dsn=DatabaseOfInterest"); 
    create table NewDataSet as select * from connection to odbc 
    (
    %sqlscript; 
); 
quit; 

說明:您嘗試使用雖然它使用了%符號,看起來像宏代碼%include語句不能真正被取代在代碼中的任何隨機點,因爲它是一個SAS語句。這實際上意味着在PROC報表和數據步驟之外發布(它可能甚至不應該有%符號,但不幸的是,這是SAS設計它的方式......)。所以這就是爲什麼它不起作用。

SAS提供了在當前正在運行的程序之外搜索宏功能的功能。如果您調用當前SAS程序中未定義的宏函數(在本例中爲%sqlscript),它將在SASAUTOS選項中指定的路徑名​​列表中查找它。如果它在其中一個SASAUTOS路徑名中找到與它正在搜索的宏完全匹配的文件,並且該文件的內容包含該宏的定義,則SAS將編譯並運行該宏。在上面的例子中,宏只是用它所包含的SQL代碼替換。

options sasautos=聲明中 - 我們只是將c:\路徑預先添加到當前位於SASAUTOS的現有路徑名列表中。它將按順序搜索路徑名,我假設我們希望我們的自定義宏覆蓋任何現有的宏,如果碰巧有衝突。您只需在每個SAS會話中指定options sasautos=一次,因此不要在每個proc sql聲明前複製/粘貼它。

Documentation for SASAUTOS。這些也被稱爲autocall宏,因此在Google中也應該會出現一些有用的點擊。

此外 - 顯然我不建議將代碼存儲在c:\中,以便根據需要進行調整。對非Windows用戶的說明 - 宏名稱和定義區分大小寫,因此保持一致!

+0

啊,很好。我花了一些時間試圖弄清楚是否可以使用宏來解決問題,但沒有想到sasautos! – Joe

+0

謝謝你的回答。我更喜歡其他答案。主要是因爲我在SSMS和R.中使用我的sql腳本文件。 – Wietze314

+0

@ Wietze314 Ahh明白了......我在下面提供了一個稍微不同的答案,那應該給你你需要的東西。 –

0

根據我之前回答的反饋,我提供了一個可以更好地解決您的確切需求的替代方法。

下面的代碼顯示了最終的程序一旦組合在一起後將如何「工作」。我們將利用這個代碼,並將其分成所作的評論指示不同的文件:

%macro myQuery;    /* FILE 1 - header.sas */ 
    select * from myTable;  /* FILE 2 - query.sql */ 
%mend;      /* FILE 3 - footer.sas */ 

/* BEGIN FILE 4 - main.sas */ 
proc sql; 
    connect to ODBC("dsn=DatabaseOfInterest"); 
    create table NewDataSet as 
    select * 
    from connection to odbc 
    (
    %myQuery; 
); 
quit ; 
/* END FILE 4 */ 

FILE1 - 「header.sas」 的樣子:

%macro myQuery;    

FILE2 - 「query.sql的「看起來就像:

select * from myTable; 

FILE3 - 」footer.sas「 的樣子:

%mend; 

FILE4將變爲:

%include "c:\header.sas" 
     "c:\query.sql" 
     "c:\footer.sas" 
     ; 

proc sql; 
    connect to ODBC("dsn=DatabaseOfInterest"); 
    create table NewDataSet as 
    select * 
    from connection to odbc 
    (
    %myQuery; 
); 
quit ; 

你可以看到,我們定義使用include語句宏。作爲宏體的查詢將保存在它自己的.sql文件中。這應該允許您繼續通過SAS和您最喜歡的SQL編輯器編輯/提交查詢。如果您有多個查詢文件,則可以重新使用頁眉和頁腳文件。