我想知道有没有办法在PL / SQL中接收已更新的行数以及使用MERGE DML语句在我的PL / SQL脚本中插入了多少行。
让我们使用这里描述的Oracle合并示例:MERGE example
此功能在我的函数中使用,但我也想记录信息已更新的行数和已插入的行数。
答案 0 :(得分:5)
有一种内置的方法可以获得单独的插入和更新计数,没有。 SQL%ROWCOUNT
会告诉你合并的行数,正如您可能已经知道的那样,但没有相应的内容可以为插入和更新获取单独的值。
This article by Adrian Billington显示了一种通过在合并中包含函数调用来获取信息的方法,这可能会增加一些开销。
MichaelS on the Oracle forums有一个类似的,也许更简单的伎俩,当然,我也不能相提并论。我很想在这里重现它,但我不确定是否允许这样做,但基本上它使用sys_context
来维持计数,这与Adrian的解决方案对包变量的方式非常相似。我会使用那个,因为它更干净,我认为它更容易遵循和维护。
仍然危险地接近仅限链接的答案,但我不想剽窃别人的工作......
答案 1 :(得分:3)
@AlexPoole指出的变通方法有效,但对我而言,奇怪的是为什么不用触发器更自然地计算更新,插入甚至可能的删除。
假设我们有简单的测试表:
create table test_table (id number, col number)
定义计数器的简单包
create or replace package pkg_test_table_counter as
procedure reset_counter;
procedure count_insert;
procedure count_update;
procedure count_delete;
function get_insert_count return number;
function get_update_count return number;
function get_delete_count return number;
end;
...和包体:
create or replace package body pkg_test_table_counter as
vUpdateCount number := 0;
vInsertCount number := 0;
vDeleteCount number := 0;
procedure reset_counter is
begin
vUpdateCount := 0;
vInsertCount := 0;
vDeleteCount := 0;
end;
procedure count_insert is
begin
vInsertCount := vInsertCount + 1;
end;
procedure count_update is
begin
vUpdateCount := vUpdateCount + 1;
end;
procedure count_delete is
begin
vDeleteCount := vDeleteCount + 1;
end;
function get_insert_count return number is
begin
return vInsertCount;
end;
function get_update_count return number is
begin
return vUpdateCount;
end;
function get_delete_count return number is
begin
return vDeleteCount;
end;
end;
要计算执行单个DML语句期间的行数,我们需要在语句触发器
之前重置它create or replace trigger trg_test_table_counter_reset
before insert or update or delete on test_table
begin
pkg_test_table_counter.reset_counter;
end;
...并在每行的触发器中增加适当的计数器:
create or replace trigger trg_test_table_counter_count
before insert or update or delete on test_table
for each row
begin
if inserting then
pkg_test_table_counter.count_insert;
end if;
if updating then
pkg_test_table_counter.count_update;
end if;
if deleting then
pkg_test_table_counter.count_delete;
end if;
end;
因此,在执行MERGE
语句后,在DML查询文本中没有额外的技巧时,总是可以获得确切数量的受影响的行:
select
pkg_test_table_counter.get_insert_count insert_count,
(
pkg_test_table_counter.get_update_count
-
pkg_test_table_counter.get_delete_count
) update_count,
pkg_test_table_counter.get_delete_count delete_count
from dual
请注意,删除操作也算作MERGE
的更新,但为了保持包对其他操作有用,有两个单独的计数器。
<强> SQLFiddle test 强>