INSERT INTO with CURSOR 在 TRIGGER 内
Posted
技术标签:
【中文标题】INSERT INTO with CURSOR 在 TRIGGER 内【英文标题】:INSERT INTO with CURSOR within a TRIGGER 【发布时间】:2019-12-21 12:06:24 【问题描述】:我正在构建一个带有光标的触发器,当表格被更新或插入时,它应该在控制台中给出一个输出。这个想法是为每个品牌计算有多少汽车在桌子。我已经尝试了很多东西,但它似乎不起作用。如果我检查 INSERT INTO 语句的简单逻辑,例如 =
SELECT marca, count(*) as cuenta
FROM coches_seg_mano
GROUP BY marca;
它将返回这些品牌下汽车的总和。但是现在我正在创建一个触发器,每次我插入或更新时,它都会在控制台输出中向我提供这些信息。我试图带来上面查询的逻辑,但它似乎不起作用。
CREATE OR REPLACE TRIGGER t_mostrarmarcas
AFTER INSERT OR UPDATE
ON coches_seg_mano
DECLARE
CURSOR totalmarcas IS
SELECT matriculo,COUNT(*) as CUENTA
FROM coches_seg_mano
GROUP BY matriculo;
vmarca coches_seg_mano.marca%TYPE;
BEGIN
FOR fila IN totalmarcas LOOP
SELECT marca INTO vmarca FROM coches_seg_mano WHERE fila.matriculo=matriculo;
DBMS_OUTPUT.PUT_LINE('Para la marca '|| vmarca ||' tenemos '|| fila.cuenta ||' vehiculos');
END LOOP;
END;
上面的那个确实给了我一个输出,但它不计数。它只会给每个条目一个 1,我会看到品牌再次出现。所以不算每个品牌下的汽车。
CREATE OR REPLACE TRIGGER t_mostrarmarcas
AFTER INSERT OR UPDATE
ON coches_seg_mano
DECLARE
CURSOR totalmarcas IS
SELECT marca,COUNT(*) as CUENTA -- this
FROM coches_seg_mano
GROUP BY marca;
vmarca coches_seg_mano.marca%TYPE;
BEGIN
FOR fila IN totalmarcas LOOP
SELECT marca INTO vmarca FROM coches_seg_mano WHERE matriculo=matriculo;
DBMS_OUTPUT.PUT_LINE('Para la marca '|| vmarca ||' tenemos '|| fila.cuenta ||' vehiculos');
END LOOP;
END;
这个会出错=
Error report -
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SYSTEM.T_MOSTRARMARCAS", line 9
ORA-06512: at "SYSTEM.T_MOSTRARMARCAS", line 9
ORA-04088: error during execution of trigger 'SYSTEM.T_MOSTRARMARCAS'
ORA-06512: at "SYSTEM.ENTRAR_VEHICULO", line 10
ORA-06512: at line 8
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested
提前致谢!
【问题讨论】:
应该是FROM coches_seg_mano c WHERE c.matriculo = fila.matriculo
。或者更好的是,将其作为连接包含在主光标中。
【参考方案1】:
这样的条件(在where
子句中)几乎总是错误的:
SELECT marca INTO vmarca FROM coches_seg_mano WHERE matriculo=matriculo;
因为它的意思是“给我一切”,即好像你甚至没有使用那个条件。
看看这样的事情是否有帮助:
SQL> create table coches_seg_mano
2 (marca varchar2(10),
3 matriculo number
4 );
Table created.
SQL> insert into coches_seg_mano values ('BMW', 100);
1 row created.
SQL> insert into coches_seg_mano values ('Audi', 200);
1 row created.
SQL>
触发器:
SQL> create or replace trigger t_mostramarcas
2 after insert or update on coches_seg_mano
3 begin
4 for cur_r in (select marca, count(*) as cuenta
5 from coches_seg_mano
6 group by marca
7 )
8 loop
9 dbms_output.put_line('Marca = ' || cur_r.marca ||
10 ', cuenta = ' || cur_r.cuenta);
11 end loop;
12 end;
13 /
Trigger created.
测试:
SQL> set serveroutput on;
SQL> insert into coches_seg_mano values ('BMW', 300);
Marca = BMW, cuenta = 2
Marca = Audi, cuenta = 1
1 row created.
SQL> insert into coches_seg_mano
2 select 'BMW', 400 from dual union all
3 select 'Mercedes', 500 from dual;
Marca = BMW, cuenta = 3
Marca = Mercedes, cuenta = 1
Marca = Audi, cuenta = 1
2 rows created.
SQL>
工作,有点……只是我不明白这种触发器的目的。只有您运行插入时,您才会看到输出。最终用户,如果他们使用 - 例如 - Oracle Forms 或 Apex 应用程序 - 将看不到任何东西。即使其他人在他们自己的 SQL*Plus 会话中运行 INSERT,您也不会看到任何内容(因为结果将显示在 他们的屏幕上,而不是您的屏幕上)。
【讨论】:
非常感谢!我有它的工作!!!!!!!我不知道您可以在 FOR 循环中的括号之间创建一个选择语句。我还有很多东西要学,但非常感谢你的帮助!!!!【参考方案2】:我认为第二个触发器中的 SELECT
不起作用是错误的,因为它返回多行,因为 matriculo=matriculo
总是正确的,例如1=1。
SELECT marca INTO vmarca FROM coches_seg_mano WHERE matriculo=matriculo;
尝试更改 where 子句。
【讨论】:
以上是关于INSERT INTO with CURSOR 在 TRIGGER 内的主要内容,如果未能解决你的问题,请参考以下文章
INSERT INTO WITH SELECT 和 WHERE(问题)
INSERT INTO with VALUES 和 SELECT STATEMENT
“GIS DICTIONARY A-Z” 查询页面开发——INSERT INTO数据库
SQL Insert into with select from multiple tables