插入新行并更新旧行(如果某些列匹配)

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

我的桌子看起来有点像这样:

CREATE TABLE `documents` 
(
    `ID` int(11) NOT NULL,
    `PERSON_ID` int(11) NOT NULL,
    `DOC_TYPE` int(11) NOT NULL,
    `DOC_INVALIDITY_ID` int(11) NOT NULL,
    `DOC_INVALIDITY_DATE` date DEFAULT NULL,
    `ACTUAL` int(11) NOT NULL
)

(`ID`, `PERSON_ID`, `DOC_TYPE`, `DOC_INVALIDITY_ID`, `DOC_INVALIDITY_DATE`, `ACTUAL`) 
(1, 100, 1, 0, NULL, 1),
(2, 100, 2, 0, NULL, 1),
(3, 200, 1, 0, NULL, 1),
(4, 200, 3, 0, NULL, 1);

我需要在添加新记录时,将现有记录的

DOC_INVALIDITY
更新为 1,将
DOC_INVALIDITY_DATE
更新为 sysdate,将
ACTUAL
更新为 0,其中
PERSON_ID
DOC_TYPE
与添加的新记录一致。

如果表中没有这样的记录,那么就进行常规的INSERT

INSERT INTO documents (ID, PERSON_ID, DOC_TYPE, DOC_INVALIDITY, DOC_INVALIDITY_DATE, ACTUAL) 
VALUES (5, 1, 1, 0, null, 1) 
ON DUPLICATE KEY UPDATE DOC_INVALIDITY = 5, ACTUAL = 0

我编写了这些查询,但它只更新具有相同 ID 的行,否则如果没有这样的 ID 则插入新行

sql oracle
1个回答
0
投票

您正在寻找的称为更新插入,或者在 Oracle 中称为合并。当某些条件匹配时,它将执行更新,但如果不匹配,则会执行插入。所以对于你的场景来说它看起来像

MERGE INTO documents d
USING (
    SELECT :new_id AS id,
           :new_person_id AS person_id,
           :new_doc_type AS doc_type,
           :new_doc_invalidity_id AS doc_invalidity_id,
           :new_doc_invalidity_date AS doc_invalidity_date,
           :new_actual AS actual
    FROM dual
) new_data
ON (d.PERSON_ID = new_data.person_id AND d.DOC_TYPE = new_data.doc_type)
WHEN MATCHED THEN
    UPDATE SET d.DOC_INVALIDITY_ID = 1,
               d.DOC_INVALIDITY_DATE = SYSDATE,
               d.ACTUAL = 0
WHEN NOT MATCHED THEN
    INSERT (ID, PERSON_ID, DOC_TYPE, DOC_INVALIDITY_ID, DOC_INVALIDITY_DATE, ACTUAL)
    VALUES (new_data.id, new_data.person_id, new_data.doc_type, new_data.doc_invalidity_id, new_data.doc_invalidity_date, new_data.actual)
© www.soinside.com 2019 - 2024. All rights reserved.