Sql server 从文件运行SQL语句以在SAS中创建数据
我在SAS方面的经验很少。我确实有SQL方面的经验 我想做以下工作: -使用存储在文本文件中的SQL语句将数据导入SAS 工作原理是复制和粘贴SQL server查询,并在SAS中将其作为传递查询运行。我得到数据(几分钟后) 但我希望能够在SSMS中管理和开发SQL脚本,并将脚本存储在SQL文件中。因此,我尝试了以下方法:Sql server 从文件运行SQL语句以在SAS中创建数据,sql-server,sas,Sql Server,Sas,我在SAS方面的经验很少。我确实有SQL方面的经验 我想做以下工作: -使用存储在文本文件中的SQL语句将数据导入SAS 工作原理是复制和粘贴SQL server查询,并在SAS中将其作为传递查询运行。我得到数据(几分钟后) 但我希望能够在SSMS中管理和开发SQL脚本,并将脚本存储在SQL文件中。因此,我尝试了以下方法: proc sql; connect to ODBC("dsn=DatabaseOfInterest"); create table NewDataSet as select
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 '%'.
**
有没有办法做到这一点?我不知道是否有真正干净的方法来解决这个问题。问题是连接到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;
包含SQL代码的文件是
C:\sqlscript.SQL
。我假设它看起来像这样:
select * from mytable;
options sasautos = ("c:\", sasautos);
proc sql;
connect to ODBC("dsn=DatabaseOfInterest");
create table NewDataSet as select * from connection to odbc
(
%sqlscript;
);
quit;
编辑文件,使其看起来像这样
%macro sqlscript;
select * from mytable;
%mend;
。。。然后将文件扩展名重命名为C:\sqlscript.sas
最后,将proc sql
代码更改为如下所示:
select * from mytable;
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),它将在SASAAUTOS选项中指定的路径名列表中查找该函数。如果它在其中一个SASAAUTOS路径名中找到一个与其搜索的宏完全匹配的文件,并且如果该文件的内容包含宏的定义,SAS将编译并运行该宏。在上面的示例中,宏只是替换其中包含的SQL代码
在options-sasaautos=
语句中,我们只是在saautos
中现有路径名列表的c:\
路径前面加上前缀。它将按顺序搜索路径名,我假设如果发生冲突,我们希望自定义宏覆盖任何现有宏。每个SAS会话只需指定一次options sasufs=
,因此不要在每个proc sql
语句之前复制/粘贴它
。这些宏也称为autocall
macros,因此在谷歌上也会出现一些有用的点击
另外-显然,我不建议将代码存储在
c:\
中,因此需要时进行调整。非windows用户注意-宏名称和定义区分大小写,因此请保持一致 根据我之前回答的反馈,我在下面提供了一种替代方法,可以更好地满足您的确切需求
下面的代码显示了最终程序组合在一起后将如何“工作”。我们将把这段代码分成不同的文件,如注释所示:
%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 */
文件1-“header.sas”将类似于:
%macro myQuery;
select * from myTable;
%mend;
文件2-“query.sql”将类似于:
%macro myQuery;
select * from myTable;
%mend;
文件3-“footer.sas”将类似于:
%macro myQuery;
select * from myTable;
%mend;
文件4将成为:
%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编辑器编辑/提交查询。如果您有多个查询文件,则可以重复使用页眉和页脚文件。能否发布SQL脚本的示例?非常感谢。我复制了你的代码。相反,
infle tempfile
我使用了infle“NetworkPath\File.sql”
我只是不确定32767是什么意思。@Wietze 32767只是说文件中的行可以长达32767个字符。这是SAS允许的最大长度。因此,您的文件中没有超过32767列的任何行,否则SAS将截断该行。技术说明(@RobPenridge):SAS允许LRECL大于32767(最大为系统最大值,对于windows,至少为100万个字符)。但是,它不允许字符变量大于该值,因此我的解决方案不适用于较大的文件,任何基于\u infle\u
的解决方案也不适用,因此Rob的建议基本上是正确的。啊,很好。我花了一点时间试图弄清楚是否可以使用宏,但没有想到sasautos!谢谢你的回答。我更喜欢另一个答案。主要是因为我在SSMS和R中也使用了我的sql脚本文件。@Wietze314 Ahh得到了它。。。我在下面提供了一个稍微不同的答案,这应该会给你你所需要的。