SQL:如果存在则更新,否则插入...但对于具有不同值的多行

Posted

技术标签:

【中文标题】SQL:如果存在则更新,否则插入...但对于具有不同值的多行【英文标题】:SQL: update if exists, else insert... but for multiple rows with different values 【发布时间】:2011-03-18 17:59:32 【问题描述】:

我想将插入/更新与 case 语句结合起来,这意味着如果它不存在我想插入该行,如果它存在则更新它,但在这两种情况下使用不同的值(更新时取决于 id ) 并在插入时,然后我设置它...

这应该发生在单个 SQL 语句中:-)

简而言之:我正在尝试将这两个语句合并为一个语句:

1)。插入/更新:

MERGE INTO table_name USING dual ON (id='id')
WHEN MATCHED     THEN UPDATE SET col1='val1', col2=val2
WHEN NOT MATCHED THEN INSERT (id, col1, col2) VALUES ('id', 'val1', val2)

2)。用大小写更新不同的值:

UPDATE SIGNALVALUE
    SET
        SIGNUMVALUE = CASE SIGID
        WHEN 49634 THEN 1.1
        WHEN 49674 THEN 2.2
        WHEN 49675 THEN 1.8
        END,
        UPDATETIME = CASE SIGID
        WHEN 49634 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
        WHEN 49674 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
        WHEN 49675 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
        END
   WHERE SIGID IN (49634, 49674, 49675)

这些陈述只是示例。实际上,要插入/更新的行更多,而且这种情况经常发生,所以我试图尽量减少查询量。

我也不能进行更新,然后查看有多少行受到影响,然后插入没有影响的行,因为我不知道需要插入的行的 ID 与需要更新的行的 ID。至少据我所知...请纠正我!

【问题讨论】:

【参考方案1】:

不必是using子句中的表,也可以使用SQL查询。 至少那是我认为你所追求的:)

merge 
 into target_table
using (select case when ... then ... else ... end as id
         from dual
      ) source_table
    on(target_table.id = source_table.id)
when matched then
   update 
      set ...
when not matched then
   insert (...)
   values (...)

如果有帮助,请告诉我。如果是这样,我可能也可以帮助编写最终查询。

【讨论】:

嘿。是的,听起来不错。其实我刚才也在玩dual。虽然有点不同:[编辑:cmets 中的 ok 代码不好]。不管怎样,你所做的看起来很有希望 :-) 但我不确定如何选择使用案例,我现在正在研究它,但如果你有任何提示,那就太好了! 好的,我让它工作了。谢谢!你的回答结合我玩的对偶=成功! :-) 下面是我的查询。如果您能看一下并告诉我可以改进的地方,我将不胜感激! @o1iver,如果您使用一些示例数据和预期结果更新您的问题,我可以为您提供帮助。 @o1iver,啊,没有看到最后一条评论 :) 很高兴我能提供帮助。如果您发现它有帮助,请不要忘记接受答案:)【参考方案2】:
MERGE INTO SIGNALVALUE USING (
SELECT 49674 as SIGID,
        TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
        '777' as SIGNUMVALUE
        FROM dual
        UNION ALL
SELECT 49675 as SIGID,
        TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
        '777' as SIGNUMVALUE
        FROM dual
        UNION ALL
SELECT 49676 as SIGID,
        TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
        '777' as SIGNUMVALUE
        FROM dual
) n
ON(SIGNALVALUE.SIGID = n.SIGID)
WHEN NOT MATCHED THEN
    INSERT (SIGID, SIGNUMVALUE, UPDATETIME) VALUES (n.SIGID, n.SIGNUMVALUE, n.UPDATETIME)
WHEN MATCHED THEN
    UPDATE SET SIGNUMVALUE=n.SIGNUMVALUE, UPDATETIME=n.UPDATETIME

【讨论】:

以上是关于SQL:如果存在则更新,否则插入...但对于具有不同值的多行的主要内容,如果未能解决你的问题,请参考以下文章

如果存在,我需要更新,否则使用 Linq 插入 SQL

如果存在则更新,否则插入[重复]

如果 id 存在则更新,否则插入 (ODBC)

SQL Server CE:如果存在更新,否则插入

mysql 表中数据不存在则插入,否则更新数据

如果记录存在则插入和更新,否则不存在竞争条件