【问题标题】:Oracle Pl/SQL trigger compilation error via SQL*PLUSOracle Pl/SQL 通过 SQL*PLUS 触发编译错误
【发布时间】:2010-12-12 23:58:19
【问题描述】:

我在通过 SQL*PLUS 编译 Oracle 触发器时遇到问题 - 我不认为我很愚蠢,但我看不出问题出在哪里。

我们有一个安装脚本,它本质上是一个批处理文件,它通过在多个脚本上调用 SQLPLUS 创建/刷新数据库中的所有对象,每个脚本包含一个视图、触发器等。首先创建表和视图,然后再创建触发器。下面的V_BS_GRIDFIELDS 视图可能会或可能不会在此时创建,或者可能稍后由不同的进程创建。该视图是一个可更新视图,因此我们在其上放置了一个触发器来将更新推送到不同的表,如下所示:

CREATE OR REPLACE FORCE TRIGGER TR_INSTUPD_BS
  INSTEAD OF INSERT OR UPDATE OR DELETE 
  ON V_BS_GRIDFIELDS
FOR EACH ROW
BEGIN

  IF INSERTING OR DELETING THEN
    NULL;
  END IF;

  IF UPDATING THEN
    -- Can only change these fields
    IF (:OLD.VISIBLE <> :NEW.VISIBLE) OR (:OLD.COMPULSORY <> :NEW.COMPULSORY) THEN 

      -- Source Table = BS_GRIDFIELDS
      IF (:OLD.SOURCE_TYPE = 0) THEN

        UPDATE BS_GRIDFIELDS BS_GF
           SET BS_GF.VISIBLE    = :NEW.VISIBLE,
               BS_GF.COMPULSORY = :NEW.COMPULSORY
         WHERE BS_GF.FIELD_NAME = :OLD.FIELD_NAME;

      END IF;
    END IF;
  END IF;
END;

问题是 oracle SQL*PLUS 似乎在第 6 行第一个空行之后停止编译触发器:

SQL> @"TR_INSTUPD_BS.sql";
SP2-0734: unknown command beginning "IF INSERTI..." - rest of line ignored.
SP2-0042: unknown command "NULL" - rest of line ignored.
SP2-0042: unknown command "END IF" - rest of line ignored.
SP2-0734: unknown command beginning "IF UPDATIN..." - rest of line ignored.
SP2-0044: For a list of known commands enter HELP
and to leave enter EXIT.
SP2-0734: unknown command beginning "IF (:OLD.V..." - rest of line ignored.
SP2-0734: unknown command beginning "IF (:OLD.S..." - rest of line ignored.
SP2-0552: Bind variable "OLD" not declared.
SP2-0042: unknown command "END IF" - rest of line ignored.
SP2-0042: unknown command "END IF" - rest of line ignored.
SP2-0042: unknown command "END IF" - rest of line ignored.
SP2-0042: unknown command "END" - rest of line ignored.
SP2-0044: For a list of known commands enter HELP
and to leave enter EXIT.

如果删除第 6 行的空白行,它似乎在第 7 行的第一个分号处停止编译:

SQL> @"TR_INSTUPD_BS.sql";

Warning: Trigger created with compilation errors.

SP2-0042: unknown command "END IF" - rest of line ignored.
SP2-0734: unknown command beginning "IF UPDATIN..." - rest of line ignored.
SP2-0734: unknown command beginning "IF (:OLD.V..." - rest of line ignored.
SP2-0734: unknown command beginning "IF (:OLD.S..." - rest of line ignored.
SP2-0552: Bind variable "OLD" not declared.
SP2-0042: unknown command "END IF" - rest of line ignored.
SP2-0042: unknown command "END IF" - rest of line ignored.
SP2-0042: unknown command "END IF" - rest of line ignored.
SP2-0042: unknown command "END" - rest of line ignored.
SP2-0044: For a list of known commands enter HELP
and to leave enter EXIT.
SQL>

我们有很多以这种方式创建的触发器,它们都有空格、分号等,并且可以正常创建。我在 Oracle 9、10、11 上测试并看到了同样的问题。有人能解释一下吗?

谢谢。

【问题讨论】:

    标签: oracle view triggers


    【解决方案1】:

    在默认设置下,SQL*Plus 无法正确处理空行,您需要发出以下命令:

    SQL> SET SQLBLANKLINES on
    

    this other SO

    更新:我回答得太快了,空行似乎不是这里的问题。我在我的数据库上尝试了您的代码,问题似乎来自 FORCE 关键字。 10gR2 documentation 没有提到这个关键字。触发器在您删除时编译。

    【讨论】:

    • 感谢您的帮助,但我们确实在早些时候尝试过,在我在这里发布之后不久,它并没有产生任何影响。正如我上面提到的,有多个触发器以与此相同的方式创建,每个触发器都有空行和分号,并且上面的触发器是唯一受这种方式影响的触发器。我们还尝试了SET SQLT ';',看看这是否是分号的问题,但同样没有效果:(
    • @Kieran:我更新了答案:问题似乎是这里的 FORCE 关键字。
    • 有趣!我没有考虑过,但我同意这似乎是问题所在。奇怪的是,当使用 PL/SQL 开发人员时,这个触发器在编译时使用或不使用 FORCE 关键字——这就是我没有想到它的原因。谢谢:)
    • PL/SQL 开发人员必须为您修复语句或静默失败。创建或替换力用于视图和类型。不是触发器的有效构造。
    猜你喜欢
    • 2012-02-09
    • 1970-01-01
    • 2014-04-07
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 2018-12-18
    • 2021-12-27
    • 2014-01-04
    相关资源
    最近更新 更多