使用插入和更新模拟 SQL 合并

Posted

技术标签:

【中文标题】使用插入和更新模拟 SQL 合并【英文标题】:Simulate SQL-Merge with insert and update 【发布时间】:2020-08-02 14:31:20 【问题描述】:

我有两个本地和远程数据库,只有一种从本地到远程的访问方式。我们只能从本地数据库插入和更新远程数据库。我写了一个合并查询,但无法远程执行,因为远程数据库无法访问源数据库,所以我想将其转换为插入和更新命令。如果远程数据库中有一行,则应该更新它,如果它不存在,则应该插入它

我的合并代码是

MERGE INTO [RemoteIp].[dbname].[dbo].[MTest] AS [Target]
USING (SELECT * FROM [dbo].[Products]
) AS [Source] ([ProductID],[ProductName],[Rate])
 ON ([Target].[PID] = [Source].[ProductID])
  WHEN MATCHED AND (
    NULLIF([Source].[ProductID], [Target].[PID]) IS NOT NULL OR NULLIF([Target].[PID], [Source].[ProductID]) IS NOT NULL OR 
    NULLIF([Source].[ProductName], [Target].[ProductName]) IS NOT NULL OR NULLIF([Target].[ProductName], [Source].[ProductName]) IS NOT NULL OR 
    NULLIF([Source].[Rate], [Target].[Rate]) IS NOT NULL OR NULLIF([Target].[Rate], [Source].[Rate]) IS NOT NULL) THEN
 UPDATE SET
  [Target].[PID] = [Source].[ProductID], 
  [Target].[ProductName] = [Source].[ProductName], 
  [Target].[Rate] = [Source].[Rate]
WHEN NOT MATCHED BY TARGET THEN
 INSERT([PID],[ProductName],[Rate]) 
 VALUES([Source].[ProductID],[Source].[ProductName],[Source].[Rate]);

我试试这个插入和更新

IF EXISTS(SELECT * FROM [RemoteIP].[DBName].[db].[Mtest])
BEGIN
    --update existing row
UPDATE
    [RemoteIP].[DBName].[db].[Mtest]
SET
    [RemoteIP].[DBName].[db].[Mtest].pid = products.ProductID,
    [RemoteIP].[DBName].[db].[Mtest].ProductName = products.ProductName,
    [RemoteIP].[DBName].[db].[Mtest].Rate = products.Rate
FROM
    Mtest tr INNER JOIN products sr
        ON tr.pid = sr.ProductID
END
ELSE
BEGIN
    --insert new row
    INSERT INTO [RemoteIP].[DBName].[db].[Mtest] (pid, ProductName, Rate)
    VALUES ([products].[ProductID], [products].[ProductName], [products].[Rate])

运行查询时出现此错误

The multi-part identifier …… could not be bound in line 4

【问题讨论】:

您不能仅通过其 IP 访问数据库。你必须先Create a Linked Server @Code 不同我检查并已创建链接服务器。我可以从 [RemoteIP].[DBName].[db].[Mtest] 中选择 * 但是当我使用更新 [RemoteIP].[DBName].[db].[Mtest] 时,它需要多部分标识符 [RemoteIP] .[DBName].[db].[Mtest] 无法绑定 另外,使用 2+ 部分命名的列将从 SQL Server 中删除。坚持使用别名并用这些来限定你的列。 所以您刚刚删除了之前的问题并重新开始。但是您仍然拒绝承认您的插入/更新尝试与 MERGE 不同,因为您的尝试将插入或更新(但不是两者)。 【参考方案1】:

下一步是检查UPDATE 命令的语法。将 [RemoteIP].[DBName].[db].[Mtest] 别名为 tr 后,命令范围内将不再有 [RemoteIP]....。只有tr。试试这个:

UPDATE
    tr
SET
    pid         = sr.ProductID,
    ProductName = sr.ProductName,
    Rate        = sr.Rate
FROM
    [RemoteIP].[DBName].[db].[Mtest] tr INNER JOIN products sr
        ON tr.pid = sr.ProductID

【讨论】:

以上是关于使用插入和更新模拟 SQL 合并的主要内容,如果未能解决你的问题,请参考以下文章

使用 if exists 使用合并 oracle sql 逻辑插入或更新

使用复合键将模拟数据插入到 SQL 中的关联表中

Django在批量插入/更新/删除时“模拟”数据库触发行为

如何使用SQL Server中的DataTable模拟“批量”插入

oracle基于3种方法的大数据量插入更新

sql 更新,插入,合并,选择INTO