我正在尝试使用MERGE编写MS SQL Server Upsert查询

时间:2017-03-16 09:07:09

标签: sql sql-server sql-server-2008 upsert sql-merge

它适用于更新现有行,但在没有条目时不会插入行。

这是CREATE TABLE:

    CREATE TABLE [dbo].[Inventory_Update_Hash_Code] ([Product_Id] [int] NOT
    NULL, [Feed_Id] [int] NOT NULL, [Hash_Code] [int] NOT NULL,
    [Last_Updated] [datetime2](0) NOT NULL
    GO

    ALTER TABLE [dbo].[Inventory_Update_Hash_Code] ADD PRIMARY KEY  
    ([Product_Id], [Feed_Id])
    GO

这是查询:

    MERGE Product_Update_Hash_Code WITH (HOLDLOCK) AS tar 
    USING (SELECT Feed_Id, Product_Id FROM Product_Update_Hash_Code WHERE
    Feed_Id = 261 AND Product_Id = 300) AS source   
    ON (tar.Feed_Id = source.Feed_Id AND tar.Product_Id = source.Product_Id) 
    WHEN MATCHED THEN 
    UPDATE SET tar.Hash_Code = 55, tar.Last_Updated = SYSUTCDATETIME() 
    WHEN NOT MATCHED
    THEN INSERT (Feed_Id, Product_Id, Last_Updated, Hash_Code) 
    VALUES (261, 300, SYSUTCDATETIME(), 55); 

看起来“UNMATCHED”子句不会被执行。我弄错了吗?

2 个答案:

答案 0 :(得分:1)

- MayBe帮助这个

MERGE Product_Update_Hash_Code WITH (HOLDLOCK) AS tar
USING (
    SELECT Feed_Id
        ,Product_Id
    FROM Product_Update_Hash_Code
    WHERE Feed_Id = 261
        AND Product_Id = 300
    ) AS source
    ON (
            tar.Feed_Id = source.Feed_Id
            AND tar.Product_Id = source.Product_Id
            )
WHEN MATCHED
    THEN
        UPDATE
        SET tar.Hash_Code = 55
            ,tar.Last_Updated = SYSUTCDATETIME()
WHEN NOT MATCHED BY TARGET THEN
            INSERT (
            Feed_Id
            ,Product_Id
            ,Last_Updated
            ,Hash_Code
            )
        VALUES (
            261
            ,300
            ,SYSUTCDATETIME()
            ,55
            );

答案 1 :(得分:1)

您不应该使用该表本身作为您的来源 - 如果您使用该表中的行作为来源,您怎么能指望它找到丢失的行。

相反,您应该从实际数据表或使用VALUES子句独立地获取输入数据:

MERGE [Inventory_Update_Hash_Code] WITH (HOLDLOCK) AS tar 
USING (VALUES (261,300,55,SYSUTCDATETIME())) AS
      source (Feed_Id,Product_ID,Hash_Code,Last_Updated)
ON (tar.Feed_Id = source.Feed_Id AND tar.Product_Id = source.Product_Id) 
WHEN MATCHED THEN 
UPDATE SET tar.Hash_Code = source.Hash_Code, tar.Last_Updated = source.Last_Updated
WHEN NOT MATCHED
THEN INSERT (Feed_Id, Product_Id, Hash_Code, Last_Updated) 
VALUES (Feed_Id,Product_ID,Hash_Code,Last_Updated); 

(请注意,CREATE TABLEMERGE之间的问题中的表格名称不匹配。我已切换到CREATE TABLE名称,以便最大限度地减少更改需要运行你的代码)