create or replace
PROCEDURE PROMOLOG1 AS
CURSOR rule IS SELECT * FROM business_rules; --this table had where conditions to use
TYPE r_cursor IS REF CURSOR;
ruleMatch r_cursor;
row_id VARCHAR2(20);
query_test VARCHAR2(400);
BEGIN
FOR a IN rule LOOP
IF a.rule_name != 'Rule1' THEN
OPEN rulematch FOR 'SELECT rowid FROM cold_promo_log_dup P WHERE EXISTS( SELECT 1 FROM cold_promo_log_dup C WHERE ' || a.condition || ' AND rowid < P.rowid)';
dbms_output.put_line('matching completed for ' || a.rule_name);
LOOP
FETCH ruleMatch INTO row_id;
EXIT WHEN rulematch%notfound;
query_test := 'INSERT INTO cold_promo_log_duplicate SELECT * FROM cold_promo_log_dup WHERE rowid = ''' || row_id ||'''' ;
dbms_output.put_line(query_test);
--EXECUTE IMMEDIATE 'INSERT INTO cold_promo_log_duplicate SELECT * FROM cold_promo_log_dup WHERE rowid = ''' || row_id || '''';
INSERT INTO cold_promo_log_duplicate SELECT * FROM cold_promo_log_dup WHERE rowid = row_id ;
EXECUTE IMMEDIATE 'DELETE FROM cold_promo_log_dup WHERE rowid = ' || row_id;
END LOOP;
END IF;
END LOOP;
END PROMOLOG1;
在oracle中执行上述过程,抛出以下错误:
Connecting to the database dedupe_preprod.
ORA-00904: "AAALJBABVAANSZDAAA": invalid identifier
ORA-06512: at "DEDUPE.PROMOLOG1", line 23
ORA-06512: at line 2
matching completed for Rule2
INSERT INTO cold_promo_log_duplicate SELECT * FROM cold_promo_log_dup WHERE rowid = 'AAALJBABvAANsZDAAA'
Process exited.
Disconnecting from the database dedupe_preprod.
当我打印rowid时,它有几个小写字母(AAALJBABvAANsZDAAA),但错误显示所有大写字母(AAALJBABVAANSZDAAA)。 DB中没有带大写的rowid,因此出现错误无效标识符 任何帮助表示赞赏。
答案 0 :(得分:3)
首先,你的row_id变量应该是ROWID类型而不是varchar2。
其次这是错误:
EXECUTE IMMEDIATE 'DELETE FROM cold_promo_log_dup WHERE rowid = ' || row_id;
你没有引用它(因此它将rowid视为标识符)。但是你为什么要在动态SQL中运行它?
如果您要保留此动态,则应使用绑定变量,因此不会丢弃共享池并提高性能。
答案 1 :(得分:0)
不要使用rowid进行循环。你这样做:你可以删除该行,并将其插入其他地方。最好的办法是使用DELETE ... RETURNING BULK COLLECT ...
,这样你就不需要使用rowid了,你可以使用集合而不是使用一行一行的for循环