我有几个数据集需要从 SAS 插入到 SQL 服务器数据库中(我的环境使用 SAS DI 4.9)。
SAS DI 附带的默认表加载器转换提供了更新/插入加载样式,并带有按 SQL 集、列或索引匹配的选项。这些都不适合我,而是抛出错误
错误:CLI 执行错误:[SAS][ODBC SQL Server 有线协议驱动程序][Microsoft SQL Server]名为“SQL_CUR608F0C44282B0000”的游标不存在。
此SAS 说明表明此问题可能与 DataDirect 驱动程序的版本有关,并且有解决方法,但在我的环境中运行的 SAS 版本的解决方法会导致读取性能不佳(这不符合我的需要)。环境由 IT 管理。
我想要做的是利用 SAS DI 的自定义转换功能来构建一些东西,它的工作方式与我的设置的用户应该具有的表加载器转换方式一样。这将需要一些使用更新 + 插入方法的 SQL 传递,但是列和表名是从转换的输入和输出以编程方式确定的,并且匹配列由用户指定,与默认转换一样。
这需要一些严肃的宏观魔术。
以下是我为更新部分尝试的内容(在[方括号]中使用匿名信息):
%let conn = %str([my libname]);
%let where_clause = &match_col0 = &match_col0;
%macro custom_upsert;
data _null_;
put 'proc sql;';
put 'connect to ODBC(&conn);';
put "execute(update &_OUTPUT";
%do i=1 %to &_OUTPUT_col_count;
put '&&_OUTPUT_col_&i_name = &&_OUTPUT_col_&i_name';
%end;
put 'from &_OUTPUT join &_INPUT on';
put 'where &where_clause';
put ') by ODBC;';
put 'quit;';
run;
%mend;
%custom_upsert;
但这因不平衡引号和引用字符串超过 262 个字符的错误而失败。
我怎样才能让它按预期工作?
编辑
这是我最终尝试使用我的 SAS 代码获取的 SQL 服务器代码,主要区别在于 SQL 代码引用了两个 SQL 服务器表,但实际上我正在尝试从 SAS 表更新:
begin
update trgt_tbl
set col1 = col1
, ...
,coln = coln
from trgt_tbl
join upd_tbl
on trgt_tbl.match_col = upd_tbl.match_col;
insert into trgt_tbl
select * from
(select
col1
, ...
,coln
from upd_tbl) as temp
where not exists
(select 1 from trgt_tbl
where match_col = temp.match_col);
end