首页 > 解决方案 > (Oracle SQL)如何在插入后使用唯一键更新表?

问题描述

我有这张桌子:

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)的行,则会收到违反唯一性的错误。此时我想修改已经存在的行并更新“Notes”字段,将 :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;

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

标签: oracleplsqldatabase-trigger

解决方案


无需使用触发器。您需要一个 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');

推荐阅读