【问题标题】:Do conditional INSERT with SQL?用 SQL 进行条件插入?
【发布时间】:2013-05-14 06:06:08
【问题描述】:

我有一个不时使用数据集更新的数据库。在这里,可能会交付已存在于数据库中的数据集。

目前我正在做一个

SELECT FROM ... WHERE val1=... AND val2=...

检查是否已经存在包含这些数据的数据集(使用 WHERE 语句中的数据)。如果这没有返回任何值,我正在执行我的 INSERT。

但这对我来说似乎有点复杂。所以我的问题是:是否有某种条件 INSERT 仅在新数据集不存在的情况下才添加它?

我正在使用 SmallSQL

【问题讨论】:

  • WHAT 数据库系统是干什么用的? SQL 只是查询语言 - 被许多数据库产品使用。 SQL 本身不是数据库产品。因此,如果您使用 MySQL、Postgres、Oracle、IBM DB2、SQL Server、Firebird 或其他任何可能的工具,请告诉我们...
  • 你在说Merge/Upsert吗?
  • 你也可以只使用 INSERT IGNORE INTO

标签: sql database smallsql


【解决方案1】:

我根据 SQL Server 中的 MERGE 语句编写此解决方案。请注意,MERGE 中的“来源”不一定是表格。

MERGE [my_target_table] t
USING (SELECT [val1]=... , [val2]=...) s
ON t.[val1]=s.[val1] AND t.[val2]=s.[val2]
WHEN MATCHED 
    THEN UPDATE set t.[val1]=s.[val1] ,
                    t.[val2]=s.[val2]
WHEN NOT MATCHED 
    THEN INSERT  ([val1], [val2])
    VALUES (s.[val1] , s.[val2]) ;

【讨论】:

    【解决方案2】:

    EXISTS 条件下是可能的。 WHERE EXISTS 测试子查询中是否存在任何记录。如果子查询返回一条或多条记录,EXISTS 返回 true。 这是一个例子

    UPDATE  TABLE_NAME 
    SET val1=arg1 , val2=arg2
    WHERE NOT EXISTS
        (SELECT FROM TABLE_NAME WHERE val1=arg1 AND val2=arg2)
    

    【讨论】:

    • “SELECT”和“FROM”之间不应该有什么(除了空格)吗?
    • @LonnieBest - 可能是 select val1, val2 from table_name ... 的意思。
    【解决方案3】:

    您可以在几乎所有关系数据库中使用单个语句和一个子查询来做到这一点。

    INSERT INTO targetTable(field1) 
    SELECT field1
    FROM myTable
    WHERE NOT(field1 IN (SELECT field1 FROM targetTable))
    

    某些关系数据库已改进上述语法,因为您所描述的是一项相当常见的任务。 SQL Server 有一个MERGE 语法和各种选项,MySQL 有可选的INSERT OR IGNORE 语法。

    编辑: SmallSQL's documentation 关于它实现的 SQL 标准的哪些部分相当稀疏。它可能无法实现子查询,因此如果您需要坚持使用 SmallSQL,您可能无法遵循上述建议或其他任何建议。

    【讨论】:

    • 如果您使用的是INSERT... VALUES ('a,' 'b,' 'c'),只需将您的语句更改为INSERT... SELECT 'a', 'b', 'c' WHERE...,不带括号。
    • 请注意,PostgresSQL 中的这种方法不能保证在同时发生插入时始终有效。
    【解决方案4】:

    我不了解 SmallSQL,但这适用于 MSSQL:

    IF EXISTS (SELECT * FROM Table1 WHERE Column1='SomeValue')
        UPDATE Table1 SET (...) WHERE Column1='SomeValue'
    ELSE
        INSERT INTO Table1 VALUES (...)
    

    根据 where 条件,如果存在则更新该行,否则将插入一个新行。

    我希望这就是你想要的。

    【讨论】:

    • 我不认为IF 是标准 SQL 的一部分
    • 这是我第一次很高兴我现在的雇主使用 MSSQL 数据库。
    【解决方案5】:

    如果您正在寻找“upsert”,目前在 SQL Server 中对单行最有效的方法之一是:

    UPDATE myTable ...
    
    
    IF @@ROWCOUNT=0
        INSERT INTO myTable ....
    

    如果您对数据集而不是单行执行此操作,也可以使用 MERGE 语法。

    如果你想INSERT 而不是UPDATE,那么你可以只写一个INSERT 语句并使用WHERE NOT EXISTS (SELECT ...)

    【讨论】:

      【解决方案6】:

      通常你制作你不想要重复的东西,并允许数据库本身拒绝插入。

      否则可以使用INSERT INTO,见How to avoid duplicates in INSERT INTO SELECT query in SQL Server?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-25
        • 1970-01-01
        • 2017-01-02
        • 1970-01-01
        • 2021-08-29
        • 2013-08-10
        • 2020-01-29
        • 1970-01-01
        相关资源
        最近更新 更多