Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 如何解决PLSQL/DELETE触发器错误中的此错误_Oracle_Plsql_Database Trigger - Fatal编程技术网

Oracle 如何解决PLSQL/DELETE触发器错误中的此错误

Oracle 如何解决PLSQL/DELETE触发器错误中的此错误,oracle,plsql,database-trigger,Oracle,Plsql,Database Trigger,我正在尝试用plsql编写一段代码,其功能如下: 在删除行之前,此触发器将检查该行是否有子行,如果是这样,子行将成为其祖父的子行,然后继续删除该行 所以,这就是我现在所拥有的: CREATE TABLE sucursal ( codsuc NUMBER (8) PRIMARY KEY, ganancia NUMBER (8) NOT NULL CHECK (ganancia > 0), sucpadre NUMBER (8) REFERENCES s

我正在尝试用plsql编写一段代码,其功能如下: 在删除行之前,此触发器将检查该行是否有子行,如果是这样,子行将成为其祖父的子行,然后继续删除该行

所以,这就是我现在所拥有的:

CREATE TABLE sucursal
(
    codsuc     NUMBER (8) PRIMARY KEY,
    ganancia   NUMBER (8) NOT NULL CHECK (ganancia > 0),
    sucpadre   NUMBER (8) REFERENCES sucursal
);

CREATE OR REPLACE TRIGGER borrar_sucursal
    BEFORE DELETE
    ON sucursal
    FOR EACH ROW
    WHEN (old.sucpadre IS NOT NULL)
BEGIN
    DBMS_OUTPUT.PUT_LINE ('Bueno pues lo intente');
    hijo_de_abuelo (:old.codsuc);
END;
/

CREATE OR REPLACE PROCEDURE hijo_de_abuelo (codigo IN sucursal.codsuc%TYPE)
IS
    gato   sucursal.sucpadre%TYPE;
BEGIN
    SELECT sucpadre
      INTO gato
      FROM sucursal
     WHERE codsuc = codigo;

    FOR gallo IN (SELECT *
                    FROM sucursal
                   WHERE sucpadre = codigo)
    LOOP
        UPDATE sucursal
           SET sucpadre = gato
         WHERE codsuc = gallo.codsuc;
    END LOOP;
END;
/
因此,当我尝试在SQL控制台中删除一行时,会发生以下情况:

SQL> delete from sucursal where codsuc = 2;
Bueno pues lo intente
delete from sucursal where codsuc = 2
            *
ERROR at line 1:
ORA-04091: table PANCRACI0.SUCURSAL is mutating, trigger/function may not see
it
ORA-06512: at "PANCRACI0.HIJO_DE_ABUELO", line 7
ORA-06512: at "PANCRACI0.BORRAR_SUCURSAL", line 3
ORA-04088: error during execution of trigger 'PANCRACI0.BORRAR_SUCURSAL'

任何帮助都会很好。

一个选项是编写一个过程来调用是否应该删除表中的行,而不是直接发出
DELETE
语句。在该过程中,在最终删除节点之前,首先重新定位子节点。但是,这可能需要您使用表更改应用程序

或者重命名该表以将其置于“背景”中

然后创建一个视图,其名称与重命名表之前的名称相同。这将视图保留在“前景”中

在该视图上,您现在可以放置一个
而不是
触发器来拦截
删除
s。触发器首先重新定位要删除的节点的子节点,然后删除“background”表中的节点


这样,您现有的代码仍然可以像以前一样使用该表。

您正在选择并更新同一个表,这是“变异”,例如,请参阅
ALTER TABLE sucursal
            RENAME TO sucursal_t;
CREATE VIEW sucursal
AS
SELECT codsuc,
       ganancia,
       sucpadre
       FROM sucursal_t;
CREATE OR REPLACE TRIGGER borrar_sucursal
                          INSTEAD OF DELETE
                          ON sucursal
                          FOR EACH ROW
BEGIN
    DBMS_OUTPUT.PUT_LINE('Bueno pues lo intente');

    UPDATE sucursal_t
           SET sucpadre = :old.sucpadre
           WHERE sucpadre = :old.codsuc;

    DELETE FROM sucursal_t
           WHERE codsuc = :old.codsuc;
END;
/