我有这张桌子:
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;
它给我错误,因为它违反了唯一性,并且不会更新。 如何修改现有行?
答案 0 :(得分: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');
答案 1 :(得分: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。