我正在尝试使用PROC SQL来查询具有数亿条记录的DB2表。在开发阶段,我想在这些记录的任意小的子集上运行我的查询(例如,1000)。我尝试使用INOBS来限制观察,但我相信这个参数只是限制SAS正在处理的记录数。我希望SAS只从数据库中获取任意数量的记录(然后处理所有这些记录)。
如果我自己编写SQL查询,我只需使用SELECT * FROM x FETCH FIRST 1000 ROWS ONLY ...
(相当于SQL Server中的SELECT TOP 1000 * FROM x
)。但PROC SQL似乎没有这样的选择。这需要很长时间才能获取记录。
问题:如何指示SAS任意限制记录数量从数据库返回。
我读过PROC SQL使用ANSI SQL,它没有行限制关键字的任何规范。也许SAS不想将其SQL语法转换为特定于供应商的关键字?没有解决方法吗?
答案 0 :(得分:28)
您是否尝试使用outobs
中的proc sql
选项?
例如,
proc sql outobs=10; create table test
as
select * from schema.HUGE_TABLE
order by n;
quit;
或者,您可以使用SQL passthrough使用DB2语法(FETCH FIRST 10 ROWS ONLY
)编写查询,但这需要您将所有数据存储在数据库中,至少是暂时的。
Passthrough看起来像这样:
proc sql;
connect to db2 (user=&userid. password=&userpw. database=MY_DB);
create table test as
select * from connection to db2 (
select * from schema.HUGE_TABLE
order by n
FETCH FIRST 10 ROWS ONLY
);
quit;
它需要更多语法,无法访问您的sas数据集,因此如果outobs
适用于您,我建议您这样做。
答案 1 :(得分:7)
当SAS通过SAS语法与数据库通信时,部分查询可以转换为DBMS语言等效 - 这称为隐式传递。查询的其余部分由SAS“后处理”以产生最终结果。 根据SAS版本,DBMS供应商和DBMS版本,在某些情况下甚至是某些连接/ libname选项,SAS语法的不同部分可以在SAS和DBMS之间进行翻译/认为兼容,因此发送由DBMS而不是SAS执行。
使用SAS SQL选项 - INOBS和OUTOBS - 我通过不同版本的SAS在MS SQL和Oracle上做了很多工作,但是我还没有看到那些转换为TOP xxx类型的查询,所以这可能不是虽然支持但是当查询只触及DMBS数据(没有加入SAS数据等)时,应该是非常可行的。
所以我认为你留下了所谓的显式传递特定的SAS SQL语法来连接到数据库。这种类型的查询如下所示:
proc sql;
connect to oracle as db1 (user=user1 pw=pasw1 path=DB1);
create table test_table as
select *
from connection to db1
( /* here we're in oracle */
select * from test.table1 where rownum <20
)
;
disconnect from db1;
quit;
在SAS 9.3中,语法可以简化 - 如果已经有LIBNAME连接,您可以重复使用它进行显式传递:
LIBNAME ORALIB ORACLE user=...;
PROC SQL;
connect to oracle using ORALIB;
create table work.test_table as
select *
from connection to ORALIB (
....
使用libname连接时,请确保在加载数据库时使用READBUFF(我通常设置约5000个左右)或INSERTBUFF选项(1000或更多)。
要查看是否发生了隐式传递,请设置sastrace选项:
option sastrace=',,,ds' sastraceloc=saslog nostsuffix;