我想知道在我的 PL/SQL 脚本使用 MERGE DML 语句时,有什么方法可以在 PL/SQL 中接收信息,更新了多少行以及插入了多少行。
让我们使用这里描述的 Oracle 合并示例:MERGE 示例
此功能在我的函数中使用,但我还想记录更新了多少行以及插入了多少行的信息。
没有一种内置的方法来获得单独的插入和更新计数,不。SQL%ROWCOUNT
会告诉您合并的行数,正如您可能已经知道的那样,但是没有等效的方法可以为插入和更新获取单独的值。
Adrian Billington 的这篇文章展示了一种通过在合并中包含函数调用来获取信息的方法,这可能会增加一些开销。
MichaelS 在 Oracle 论坛上有一个类似的,也许更简单的把戏,当然,我也不能把它归功于任何人。我很想在这里重现它,但我不确定这是否允许,但本质上它是sys_context
用来维持计数的,这与 Adrian 的解决方案对包变量所做的方式大致相同。我会使用那个,因为它更干净,而且我认为它更容易遵循和维护。
仍然非常接近仅链接的答案,但我也不想抄袭别人的工作......
@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
,但为了使包对其他操作有用,有两个单独的计数器。