我正在尝试使用 SAS 的 proc sql 内的 forall 循环更新超过 5 亿条记录,我想从 schema.HashedCNumbers 中获取 NG_OFRRELPRD1 的值并将其放入 schema2.archu 两个表中的 UNIQUE_ID 字段中。这是我使用的代码:
proc sql noprint;
connect using user as oracle ;
execute(
DECLARE
CURSOR cur_UNIQ IS SELECT UNIQUE_ID FROM schema.HashedCNumbers;
TYPE tab_KEY IS TABLE OF cur_UNIQ%ROWTYPE INDEX BY PLS_INTEGER;
array_unique_id_KEY tab_KEY;
BEGIN
dbms_output.put_line(CHR(9)||'Zaczynam kopiowanie danych: '||TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS'));
OPEN cur_UNIQ;
LOOP FETCH cur_UNIQ BULK COLLECT INTO array_unique_id_KEY LIMIT 10000;
EXIT WHEN array_unique_id_KEY.count=0;
FORALL indx IN 1 .. array_unique_id_KEY.COUNT SAVE EXCEPTIONS
UPDATE schema2.arch SET NG_OFRRELPRD1 = (SELECT NG_OFRRELPRD1 FROM schema.HashedCNumbers WHERE
schema.HashedCNumbers.UNIQUE_ID=array_unique_id_KEY(indx).UNIQUE_ID);
COMMIT WRITE batch WAIT;
END LOOP;
CLOSE cur_UNIQ;
dbms_output.put_line(CHR(9)||'Dane skopiowane: '||TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS'));
END;
by oracle;
disconnect from oracle;
QUIT;
sas oracle 连接是正确的,因为我可以搞乱数据库。问题是这个循环不尊重我的 WHERE 子句,并且不通过其他表中的 UNIQUE_ID 进行连接。它采用 NG_OFRRELPRD 的第一个值并在第一次迭代中更新目标表中的每一行。
这里可能出了什么问题?
我想你想检查你正在更新的值;我建议它不是 NG_OFRRELPRD 的第一个值,并更新除最后一行之外的每一行。它并不是忽略你的 where 子句,而是你把它放在了错误的地方。如果您格式化查询,您将看到该子句仅出现在子选择中,而不出现在更新中。因此,如果没有 where 子句,每行都会使用为集合中所选的每行选择的值进行更新。
UPDATE CDM.MDM_EVN_OFFER_ARCH
SET NG_OFRRELPRD1 = (SELECT NG_OFRRELPRD1
FROM CMBATCH.HashedCNumbers
WHERE CMBATCH.HashedCNumbers.UNIQUE_ID=array_unique_id_KEY(indx).UNIQUE_ID);
也许你的意思是:
update cdm.mdm_evn_offer_arch offer
set ng_ofrrelprd1 = (select ng_ofrrelprd1
from cmbatch.hashedcnumbers hnum
where huum.unique_id=array_unique_id_key(indx).unique_id)
where offer.unique_id = array_unique_id_key(indx).unique_id;