PL/SQL Oracle Mutant table-如何遇到这个问题?

Posted

技术标签:

【中文标题】PL/SQL Oracle Mutant table-如何遇到这个问题?【英文标题】:PL/SQL Oracle Mutant table-how to encounter this issue plz? 【发布时间】:2019-07-19 01:58:12 【问题描述】:

第一个要求是确保我们在这个城市只有一个分店, Banch (idBranch(PK), city) 用于更新和插入

我的想法是创建一个包含第一个的所有数据的临时表,这样我就可以逃避 ora 错误这是我编写的代码,我正面临错误 PL/SQL: ORA-00903 和我在这种情况下,我不太确定一个触发器是否可以完成工作,因为它应该可以用于插入和更新。我需要你的建议,谢谢。

  ` CREATE TABLE TEMP_BRANCH AS SELECT NumBranch, CITY FROM BRANCH;
    CREATE OR REPLACE TRIGGER checkUniqueBranchPerCity
    BEFORE INSERT OR UPDATE ON BRANCH  
    REFERENCING
        NEW AS nextLine
    FOR EACH ROW
    BEGIN
    LOCK TABLE TEMP_BRANCH IN ROW SHARE MODE;

     FOR line IN (SELECT * FROM TEMP_BRANCH) LOOP 
       IF :nextLine.City = line.City  THEN
         RAISE_APPLICATION_ERROR;
       END IF;
    END LOOP;

    DELETE * FROM TEMP_BRANCH;
    END;
   / `

【问题讨论】:

【参考方案1】:

ORA-00903 是“无效的表名”。我怀疑这是因为你在nextLine前面放了一个冒号,即你写了

IF :nextLine.City = line.City  THEN

应该是什么时候

IF nextLine.City = line.City  THEN

但我建议去掉 REFERENCING 子句,只在触发器中使用 :NEW 和 :OLD ,因为这样可以减少混淆。所以使用

CREATE TABLE TEMP_BRANCH AS SELECT NumBranch, CITY FROM BRANCH;

CREATE OR REPLACE TRIGGER checkUniqueBranchPerCity
  BEFORE INSERT OR UPDATE ON BRANCH  
  FOR EACH ROW
BEGIN
  LOCK TABLE TEMP_BRANCH IN ROW SHARE MODE;

   FOR line IN (SELECT * FROM TEMP_BRANCH) LOOP 
     IF :NEW.City = line.City  THEN
       RAISE_APPLICATION_ERROR;
     END IF;
  END LOOP;
END;
/

我还建议你去掉触发器中的 DELETE 语句,因为它会在触发器第一次触发时删除 TEMP_BRANCH 的内容。

【讨论】:

非常感谢您的帮助。我仍然认为我的想法是错误的,因为当我在分支中更新或插入时,在 temp_table 中没有插入或更新数据,它是分支的副本。因此,在第二次更新或插入触发器时不会注意到错误。我应该找到一种方法来做到这一点,而不会创建重复的不必要的表

以上是关于PL/SQL Oracle Mutant table-如何遇到这个问题?的主要内容,如果未能解决你的问题,请参考以下文章

oracle table()函数

pl/sql连接oracle数据库tables里面不显示表。

java - 如何将table%rowtype的oracle pl/sql out参数引用为java中的对象

如何在 Oracle PL/SQL 中编写此数据库比较?

Oracle_PL/SQL 集合

PL/SQL ORACLE 查询作为结果