【问题标题】:Using INSERT INTO... SELECT in TRIGGER在 TRIGGER 中使用 INSERT INTO... SELECT
【发布时间】:2017-02-02 13:05:55
【问题描述】:

我要问的问题已经存在了。但我没有答案。

请参考以下链接。 ORACLE TRIGGER INSERT INTO ... (SELECT * ...)

我在一个表中有大约 600 列。在此表中每次插入后,我需要在另一个备份表中插入 新行

请说明如何在触发器中使用“INSERT INTO TABLE_NAME2 SELECT * FROM TABLE_NAME1”查询。

注意:不要在插入或选择子句中指定列

两个表的结构相同。在触发器中指定所有列名很困难,而且如果添加了新列,我们也需要在触发器中添加。

【问题讨论】:

  • 也许制作一个在表 2 中插入数据的过程会更容易?
  • @Tenzin - 不,这个插入是通过网页。所以包在这里不适用。
  • @Krzosik - 那里大约有 600 列。你想让我把所有的列名都写上吗?
  • 如果业务逻辑在数据库中并且您只是调用了一个过程来插入 table_1 记录,这将不是问题。然后,该过程将实现“当 table_1 记录创建时,在 table_2 中创建备份”的业务逻辑。这很容易,业务数据的逻辑将与业务数据一起使用。触发器只是一种将业务逻辑分散在错误位置的解决方法。

标签: oracle plsql


【解决方案1】:
    SQL> CREATE or REPLACE TRIGGER emp_after_insert AFTER INSERT ON emp
FOR EACH ROW
DECLARE
BEGIN
insert into emp_backup values (:new.empid, :new.fname, :new.lname);
DBMS_OUTPUT.PUT_LINE('Record successfully inserted into emp_backup table');
END;

参考: http://www.tech-recipes.com/rx/19839/oracle-using-the-after-insert-and-after-update-triggers/

【讨论】:

  • 这里您只提到了 3 列。我要求不提列,因为我在一个表中有大量列。所以打算用select * from。
  • 您需要将列至少写出一次。
【解决方案2】:

您应该使用复合触发器。此触发器应如下所示:

CREATE OR REPLACE TRIGGER t_copy_table1
FOR INSERT ON table1
COMPOUND TRIGGER
    v_id number;

BEFORE EACH ROW IS
BEGIN
    v_id := :new.id;
END BEFORE EACH ROW;

AFTER STATEMENT IS
BEGIN 
    insert into table2 select * from table1 where id=v_id;
END AFTER STATEMENT;
END t_copy_table1;

【讨论】:

  • 这仅适用于主表中的单个 INSERT。如果在主表上执行了 INSERT AS SELECT,则只会将最后一行复制到备份表中。您需要引入一个 PL-SQL 表来存储 ID,并且您会遇到内存考虑问题。
  • @MarcoPolo 好的,但没有说将为此表插入作为选择。我认为单次插入是正确的方法。
  • 这里还有一个条件,你在上面触发器中提到的id可能有重复。但我只需要在第一个表中新插入的最后一个条目。
  • @CHANDRUS 所以使用这个表的主键列,我只使用 id 来显示示例
猜你喜欢
  • 1970-01-01
  • 2012-01-23
  • 2021-07-22
  • 2012-10-05
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 2014-03-22
  • 1970-01-01
相关资源
最近更新 更多