sql - 如果使用触发器出现相同的名称,如何进行增量?
问题描述
我有一张桌子:
id
name
amount
如果name
插入了相同的内容,amount
则应递增。否则,以 0 金额插入。
如何创建具有给定条件的触发器?
解决方案
你真的不应该那样做。AMOUNT
列有效地计算NAME
了该表中出现的次数。你总能数出来,不是吗?那么,这样做的目的是什么?
如果您想知道在某个其他名称(等于前一个名称)之前(或之后)插入了哪个名称,请按(如果它是增量的,例如标识列或者它是否从序列中获取其值)对它们进行排序。ID
如果ID
不是增量,则添加DATE_INSERTED
列(并按其排序;或应用按 排序ROW_NUMBER
值的分析函数DATE_INSERTED
)。
另外,如果您删除其中一个重复名称会怎样?您是否会追溯减少AMOUNT
所有先前实例的列NAME
?
但是,如果你坚持,这里有一个选择。由于您不能只从要插入的表中进行选择(由于 mutating table 错误),因此我使用了复合触发器。“插入数量 0”的部分是通过设置列的默认值来完成的(您不需要任何代码)。
SQL> create table test
2 (id number primary key,
3 name varchar2(20),
4 amount number default 0);
Table created.
SQL> create or replace trigger trg_ai_test
2 for insert on test
3 compound trigger
4
5 type test_rt is record (id test.id%type,
6 name test.name%type);
7 type rli_t is table of test_rt index by pls_integer;
8 g_rli rli_t;
9
10 after each row is
11 begin
12 g_rli(g_rli.count + 1).id := :new.id;
13 g_rli(g_rli.count).name := :new.name;
14 end after each row;
15
16 after statement is
17 l_cnt number;
18 begin
19 for i in 1 .. g_rli.count loop
20 dbms_output.put_Line('x');
21 dbms_output.put_line(i ||' '|| g_rli(i).id ||' '||g_rli(i).name);
22 select count(*) into l_cnt
23 from test
24 where name = g_rli(i).name;
25
26 update test set
27 amount = l_cnt
28 where id = g_rli(i).id;
29 end loop;
30
31 end after statement;
32 end trg_ai_test;
33 /
Trigger created.
SQL>
测试:
SQL> insert into test (id, name) values (1, 'little');
1 row created.
SQL> insert into test (id, name) values (2, 'foot');
1 row created.
SQL> insert into test (id, name) values (3, 'little');
1 row created.
SQL> insert into test (id, name) values (9, 'little');
1 row created.
SQL> select * from test;
ID NAME AMOUNT
---------- -------------------- ----------
1 little 1
2 foot 1
3 little 2
9 little 3
SQL>
或者,一个更简单的解决方案(如上所述),而不使用那么多代码:
SQL> select id, name,
2 row_number() over (partition by name order by id) as amount
3 from test;
ID NAME AMOUNT
---------- -------------------- ----------
2 foot 1
1 little 1
3 little 2
9 little 3
SQL>
推荐阅读
- android - 如何远程安装原型 Android 应用程序(无需 USB/Wifi 连接)
- javascript - 将变量传递给创建的钩子 Vue.js 以供 Firestore 参考
- python - Keras 没有看到训练和验证文件夹中的所有图像
- python - Python __str__ 内类混淆
- java - 可以在 Spring 的控制器之外使用 ResponseEntity 吗?
- python - 单步执行我的自定义环境(Python)时,Openai 的 PPO2 模型返回 NAN
- python - 如何在 python 中使用 plt.savefigure() 保存大量图像?
- swift - Swift MapKit 叠加层不会显示在地图上
- java - Android Studio 无法解析方法 SetOnItemClickListener (Java)
- c++ - 未找到 CMake 自定义编译器链接器语言