2014-01-23 46 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编辑器编辑/提交查询。如果您有多个查询文件,则可以重新使用页眉和页脚文件。