打开新帐户时插入表格的触发器

时间:2012-12-07 05:08:01

标签: oracle plsql

customers:
+------------+--------------+ 
| cid        | Name         | 
+------------+--------------+ 
| 1          | Bob          |
| 2          | John         | 
| 3          | Jane         | 
+------------+--------------+ 
accounts:
+------------+--------------+ 
| aid        | type         | 
+------------+--------------+ 
| 1          | Checking     |
| 2          | Saving       | 
| 3          | Checking     | 
+------------+--------------+ 
transactions:
+------------+--------------+--------------+--------------+ 
| tid        | cid          | aid          | type         |
+------------+--------------+--------------+--------------+ 
| 1          | 1            | 1            | Open         |
| 2          | 2            | 3            | Open         |
| 3          | 1            | 2            | Open         |
| 4          | 2            | 3            | Deposit      |
+------------+--------------+--------------+--------------+

我正在尝试编写一个触发器,在成功打开新帐户时写入日志表。

现在我有这个:

CREATE OR REPLACE TRIGGER acc_opened
BEFORE INSERT ON transactions
FOR EACH ROW
DECLARE
    c_name customers.name%TYPE;
BEGIN
    IF :new.type = 'Open' THEN
        SELECT name into c_name
        FROM customers c
        WHERE c.cid = :new.cid;

        INSERT INTO logs (who, what) VALUES (c_name, 'An account has been opened');
END;
/    

我所拥有的代码不起作用,不知道从哪里开始。

触发器完成,但是当它触发时,我收到以下错误消息:

PLS-00103:当遇到以下情况之一时遇到符号“END”:(如果使用<<继续关闭当前删除获取锁定插入打开,则开始情况声明退出goto如果loop mod null pragma raise返回选择更新rollback savepoint set sql execut commit forall merge pipe purge

1 个答案:

答案 0 :(得分:0)

previous question一样,如果要引用新行数据的特定列,则需要使用:new伪记录。所以,至少,

SELECT cid 
  INTO c_id
  FROM transactions t
 WHERE t.aid = aid;

需要

SELECT cid 
  INTO c_id
  FROM transactions t
 WHERE t.aid = :new.aid;

除此之外,在将行插入transactions故事之前,您确定该行存在于accounts表中吗?假设您有正常的外键约束,我通常希望在将行插入accounts表之前将行插入transactions表。

名称transactions似乎也很奇怪。如果这只是将客户ID映射到帐户ID,transactions似乎是一个相当差的名称。如果该表实际存储了事务,我不确定它为什么会有客户ID。但如果它确实存储了交易,则必须有一些其他表将客户映射到帐户。

在更新的触发器中,您缺少END IF声明

CREATE OR REPLACE TRIGGER acc_opened
  BEFORE INSERT ON transactions
  FOR EACH ROW
DECLARE
  c_name customers.name%TYPE;
BEGIN
  IF :new.type = 'Open' 
  THEN
    SELECT name 
      into c_name
      FROM customers c
     WHERE c.cid = :new.cid;

     INSERT INTO logs (who, what) 
       VALUES (c_name, 'An account has been opened');
  END IF;
END;