oracle - (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;
它给了我违反唯一性的错误并且不更新。如何修改现有行?
解决方案
无需使用触发器。您需要一个 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');
推荐阅读
- jenkins - 如果自上次提交以来某个目录中的任何文件已被修改(不是 FS 触发器),让 Jenkins 执行构建步骤
- swiftui - 如何为 SwiftUI 制作滑动手势?
- c# - 数据表计算时,对象不能从 DBNull 转换为其他类型
- python - 使用另一个列表将列表解压缩到单独的列表中
- gekko - Gekko的工业应用
- bash - 在 MacOS 上的 bash 脚本中使用关联数组
- r - 如何对包含数字的字符向量进行排序
- docker - Hazelcast 分布式缓存是否适用于 Docker Swarm
- mongoose - 猫鼬的连接是特定于版本的吗?
- java - 管理 ImageIcons 的 Java 最佳实践