(Oracle SQL)插入后如何用唯一键更新表?

问题描述 投票:0回答:2

我有这张桌子:

CREATE TABLE STATO_VERS_METODO(
    METODO INT NOT NULL,
    PROGETTO INT NOT NULL,
    VERS NUMBER NOT NULL,
    STATO VARCHAR2(20) DEFAULT 'Nuovo' NOT NULL,
    NOTA_VERSM VARCHAR2(500),
    CONSTRAINT UK_STATO_METODO UNIQUE(METODO, PROGETTO, VERS)
);

如果我使用相同的唯一键(metodo,progetto和vers)插入一行,则会因违反唯一性而收到错误消息。此时,我想修改已经存在的行并更新“注释”字段,将:NEW.NOTE的值添加到现有行中。我写了这个触发器:

create or replace TRIGGER AGGIORNA_NOTA_METODO
BEFORE INSERT ON STATO_VERS_METODO
FOR EACH ROW
DECLARE
    n_righe INT;
    nota VARCHAR2(500);

BEGIN
    SELECT COUNT(*) INTO n_righe FROM STATO_VERS_METODO WHERE METODO = :NEW.METODO AND PROGETTO = :NEW.PROGETTO AND VERS = :NEW.VERS;
    IF(n_righe > 0)
    THEN
        IF(:NEW.STATO = 'Modificato')
        THEN
            SELECT NOTA_VERSM INTO nota FROM STATO_VERS_METODO WHERE METODO = :NEW.METODO AND PROGETTO = :NEW.PROGETTO AND VERS = :NEW.VERS;
            UPDATE STATO_VERS_METODO
            SET NOTA_VERSM = nota||CHR(10)||:NEW.NOTA_VERSM WHERE METODO = :NEW.METODO AND PROGETTO = :NEW.PROGETTO AND VERS = :NEW.VERS;
        END IF;
    END IF;



END;

它为我带来了违反唯一性的错误,并且不会更新。如何修改现有行?

oracle plsql database-trigger
2个回答
4
投票
无需使用触发器。您需要一个Merge语句-

MERGE INTO STATO_VERS_METODO SVM USING (SELECT 'new_metodo' METODO, 'new_progetto' PROGETTO, 'new_vers' VERS FROM DUAL) D ON (SVM.METODO = D.METODO) WHEN MATCHED THEN UPDATE SET NOTA_VERSM = NOTA_VERSM || CHR(10) || D.NOTA_VERSM WHERE SVM.METODO = D.METODO ,SVM.PROGETTO = D.PROGETTO ,SVM.VERS = D.VERS WHEN NOT MATCHED THEN INSERT (METODO, PROGETTO, VERS, NOTA_VERSM) VALUES ('new_metodo', 'new_progetto', 'new_vers', 'new_versm');


0
投票
正如Ankit指出的那样,您不需要使用触发器,但是如果您是初学者,我会发布带有触发器的答案。

创建表后,让下面的语句插入第一行。

INSERT INTO STATO_VERS_METODO(METODO, VERS, PROGETTO, NOTA_VERSM) VALUES (1, 1, 10, 'Source code changed')

现在我们的表有一行,如下所示:

METODO | VERS | PROGETTO | STATO | NOTA_VERSM ----------------------------------------------------------- 1 | 10 | 1 | Nuovo | Source code changed

现在,由于您声明了具有约束的表,因此无法再插入具有相同约束的另一行(METODO,PROGETTO和VERS),因此类似:

INSERT INTO STATO_VERS_METODO(METODO, VERS, PROGETTO, NOTA_VERSM) VALUES (1, 1, 10, 'New String')

将引发异常。

ORA-00001: unique constraint (****.UK_STATO_METODO) violated ORA-06512

因此,如果要更改值,则需要执行UPDATE。但是,正如您在注释部分所说的那样,您需要将旧字符串和新字符串连接起来。一种解决方案是按如下方式实现触发器。

create or replace TRIGGER AGGIORNA_NOTA_METODO BEFORE UPDATE ON STATO_VERS_METODO FOR EACH ROW BEGIN :NEW.STATO := 'Modificato'; :NEW.NOTA_VERSM := :OLD.NOTA_VERSM || ' ' || :NEW.NOTA_VERSM; END;

更新行:

UPDATE STATO_VERS_METODO SET NOTA_VERSM = 'Minor fix' WHERE METODO = 1 AND PROGETTO = 10 AND VERS = 1;

最后,我们的表格如下:

METODO | VERS | PROGETTO | STATO | NOTA_VERSM -------------------------------------------------------------------- 1 | 10 | 1 | Modificato | Source code changed Minor fix

同样,在编写触发器时,触发器也会生成变异表异常learn more
© www.soinside.com 2019 - 2024. All rights reserved.