使用 passthrough SQL 插入 DB2 fom SAS 数据集

Inserting into DB2 fom SAS dataset with passthrough SQL

我对 SAS 和 DB2 还是个新手。我有一个 DB2 Table,其中有一列存储编码为时间戳的值。我正在尝试从我的工作目录中的 SAS 数据集中将数据加载到此列。然而,其中一些时间戳对应于 01-01-1582 之前的日期,不能作为日期时间值存储在 SAS 中。它们被存储为字符串。

这意味着如果我想将这些值加载到 DB2 table 我必须首先使用 TIMESTAMP() DB2 函数将它们转换为时间戳,据我所知,这需要传递 SQL 与执行语句(与 SAS ACCESS libname 方法相反)。例如,为了写入单个值,我执行以下操作:

PROC SQL;
    connect to db2 (user = xxxx database = xxxx password = xxxx);
    execute (insert into xxxx.xxxx (var) values (TIMESTAMP('0001-01-01-00.00.00.000000'))) by db2;
    disconnect from db2;
quit;

如何为源数据集中的所有值实现这一点? select ... from execute 命令中的语句不起作用,因为据我所知,我无法从 DB2 连接中引用 SAS Work 目录。

最终我可以编写一个宏来执行上面的 PROC SQL 块,并在每次观察的数据步骤中调用它,但我想知道是否有更简单的方法来执行此操作。更改变量的类型不是一个选项。

提前致谢。

一种复杂的解决方法是使用 call execute:

data _null_;
set sas_table;
call execute("PROC SQL;
              connect to db2 (user = xxxx database = xxxx password = xxxx);
              execute (
                 insert into xxxx.xxxx (var)
                 values (TIMESTAMP('"||strip(dt_string)||"'))
                ) by db2;
              disconnect from db2;
              quit;");
run;

其中 sas_table 是您的 SAS 数据集,其中包含存储为字符串的日期时间值,并存储在名为 dt_string 的变量中。

这里发生的是,对于数据集中的每个观察,SAS 将执行 execute 调用例程的参数,每次使用当前值 dt_string

另一种方法使用宏而不是调用 execute 来做基本相同的事情:

%macro insert_timestamp;
  %let refid = %sysfunc(open(sas_table));
  %let refrc = %sysfunc(fetch(&refid.));
  %do %while(not &refrc.);
    %let var = %sysfunc(getvarc(&refid.,%sysfunc(varnum(&refid.,dt_string))));

    PROC SQL;
      connect to db2 (user = xxxx database = xxxx password = xxxx);
      execute (insert into xxxx.xxxx (var) values (TIMESTAMP(%str(%')&var.%str(%')))) by db2;
     disconnect from db2;
    quit;

    %let refrc = %sysfunc(fetch(&refid.));
  %end;
  %let refid = %sysfunc(close(&refid.));
%mend;
%insert_timestamp;

编辑:我想您也可以使用 SAS/ACCESS 在 DB2 中按原样加载 table,然后使用 [=] 将字符串转换为时间戳31=] 传递。像

libname lib db2 database=xxxx schema=xxxx user=xxxx password=xxxx;
data lib.temp;
set sas_table;
run;
PROC SQL;
    connect to db2 (user = xxxx database = xxxx password = xxxx);
    execute (create table xxxx.xxxx (var TIMESTAMP)) by db2;
    execute (insert into xxxx.xxxx select TIMESTAMP(dt_string) from xxxx.temp) by db2;
    execute (drop table xxxx.temp) by db2;
    disconnect from db2;
quit;