(Oracle SQL) Как обновить таблицу с уникальным ключом после вставки? - PullRequest
0 голосов
/ 10 января 2020

У меня есть эта таблица:

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)
);

Если я вставляю строку с тем же уникальным ключом (метод, прогетто, верс), я получаю ошибку за нарушение уникальности. На этом этапе я хочу изменить уже существующую строку и обновить поле «Примечания», добавив значение: 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;

Он выдает ошибку за нарушение уникальности и не обновляет. Как я могу изменить существующую строку?

Ответы [ 2 ]

4 голосов
/ 10 января 2020

Нет необходимости использовать триггер. Вместо этого вам нужен оператор слияния -

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 голосов
/ 10 января 2020

Как указал 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

Также ваш триггер, как вы написали, генерирует исключение мутирующей таблицы, узнать больше .

...