SQL%ROWCOUNT 未提供动态 SQL Oracle 中的 BULK COLLECT 和 FORALL PL/SQL 所需的结果
SQL%ROWCOUNT is not providing desired outcome with dynamic SQL Having BULK COLLECT and FORALL in Oracle PL/SQL
SQL%ROWCOUNT 返回 运行 考虑的计数 (10),而不是更新记录的确切数量。期望 SQL%ROWCOUNT 应该提供更新的实际记录数。请建议我如何完成任务。
触发动态的代码SQL
FORALL indx IN 1 .. l_account_data.COUNT --assume 10 as count
SAVE EXCEPTIONS
EXECUTE IMMEDIATE dynamic_sql_query USING l_account_data (indx);
DBMS_OUTPUT.put_line ('Successful UPDATE of '|| TO_CHAR (SQL%ROWCOUNT) || ' record');
COMMIT;
dynamic_sql_query
BEGIN
SELECT clmn_x, clmn_y
BULK COLLECT INTO l_subscr_data
FROM table_x e, table_y c
WHERE c.ref_id = :account_no AND e.account_no = c.account_no;
FORALL indx IN 1 .. l_subscr_data.COUNT
UPDATE table_z ciem --this update will update multiple records for each account
SET ciem.ext_id = ciem.sub_no || ROWID
WHERE ciem.sub_no = l_subscr_data (indx).clmn_x
AND ciem.subscr_no_resets = l_subscr_data (indx).clmn_y
AND ciem.status IN (1,2);
END;
您的外部 execute immediate
调用不知道动态 SQL 内部发生了什么;它不知道自己在做什么,也不知道它可能影响或不影响多少行。
要获得准确的计数,您需要修改动态语句以添加如下内容:
FOR indx IN 1 .. l_subscr_data.COUNT LOOP
:total_count := :total_count + coalesce(SQL%BULK_ROWCOUNT(indx), 0);
END LOOP;
并将您的外部调用更改为 (a) 传递一个额外的 IN OUT 绑定变量来跟踪总计数,并且 (b) 使用 FOR 循环而不是 FORALL,因为这似乎只在第一个之后保留值动态调用(不确定是否已记录或错误)。所以像:
...
l_total_count number := 0;
...
FOR indx IN 1 .. l_account_data.COUNT LOOP
EXECUTE IMMEDIATE dynamic_sql_query
USING l_account_data (indx), in out l_total_count;
END LOOP;
DBMS_OUTPUT.put_line ('Successful UPDATE of '|| TO_CHAR (l_total_count) || ' record');
db<>fiddle demo 数据 made-up。
SQL%ROWCOUNT 返回 运行 考虑的计数 (10),而不是更新记录的确切数量。期望 SQL%ROWCOUNT 应该提供更新的实际记录数。请建议我如何完成任务。
触发动态的代码SQL
FORALL indx IN 1 .. l_account_data.COUNT --assume 10 as count
SAVE EXCEPTIONS
EXECUTE IMMEDIATE dynamic_sql_query USING l_account_data (indx);
DBMS_OUTPUT.put_line ('Successful UPDATE of '|| TO_CHAR (SQL%ROWCOUNT) || ' record');
COMMIT;
dynamic_sql_query
BEGIN
SELECT clmn_x, clmn_y
BULK COLLECT INTO l_subscr_data
FROM table_x e, table_y c
WHERE c.ref_id = :account_no AND e.account_no = c.account_no;
FORALL indx IN 1 .. l_subscr_data.COUNT
UPDATE table_z ciem --this update will update multiple records for each account
SET ciem.ext_id = ciem.sub_no || ROWID
WHERE ciem.sub_no = l_subscr_data (indx).clmn_x
AND ciem.subscr_no_resets = l_subscr_data (indx).clmn_y
AND ciem.status IN (1,2);
END;
您的外部 execute immediate
调用不知道动态 SQL 内部发生了什么;它不知道自己在做什么,也不知道它可能影响或不影响多少行。
要获得准确的计数,您需要修改动态语句以添加如下内容:
FOR indx IN 1 .. l_subscr_data.COUNT LOOP
:total_count := :total_count + coalesce(SQL%BULK_ROWCOUNT(indx), 0);
END LOOP;
并将您的外部调用更改为 (a) 传递一个额外的 IN OUT 绑定变量来跟踪总计数,并且 (b) 使用 FOR 循环而不是 FORALL,因为这似乎只在第一个之后保留值动态调用(不确定是否已记录或错误)。所以像:
...
l_total_count number := 0;
...
FOR indx IN 1 .. l_account_data.COUNT LOOP
EXECUTE IMMEDIATE dynamic_sql_query
USING l_account_data (indx), in out l_total_count;
END LOOP;
DBMS_OUTPUT.put_line ('Successful UPDATE of '|| TO_CHAR (l_total_count) || ' record');
db<>fiddle demo 数据 made-up。