【问题标题】:SQL server MERGE 2 source/target tables with inner joinSQL Server MERGE 2 具有内部联接的源/目标表
【发布时间】:2014-11-14 07:12:31
【问题描述】:

我有一个包含 2 个表的 SQL 服务器数据库,这些表由一个 ID 字段连接,如下所示:

Table 1
ID, Selection, Field1, Field2

Table 2
ID, Field3, Field4

这些表由具有级联删除约束的外键连接,因此如果删除表 1 中的字段,则表 2 中与 ID 匹配的所有字段也将被删除(但您知道)

我有另一个存储过程,它通过选择两个表来提取必要的字段:

    SELECT [Table2].* FROM [Table2] INNER JOIN [Table1] ON [Table1].[ID] = [Table2].[ID] WHERE [Table1].Selection = @selectionParameter

我想从我的 c# 程序中更新这些表。我之前一直在做以下事情:

DELETE FROM [Table1] WHERE Selection = @selectionParameter

INSERT INTO [Table1] SELECT * FROM @table1Parameter (user defined table type passed in from c#)

INSERT INTO [Table2] SELECT * FROM @table2Parameter

我现在想通过不强制完全删除和重新插入所有字段而是执行合并来简化此操作。

到目前为止,我在 Table1 上具有合并功能,但似乎无法正确建立与 Table2 的关系。

这是我目前所拥有的:

MERGE INTO [Table1] AS target
USING @Table1Parameter AS source
ON target.ID = source.ID
AND target.Selection = @selectionParameter

WHEN NOT MATCHED BY TARGET
    THEN INSERT (ID, Selection, Field1, Field2) VALUES (source.ID, etc)
WHEN NOT MATCHED BY SOURCE AND target.Selection = @selectionParameter
    THEN DELETE;

这是一个非常相似的查询: SQL Server MERGE + Joining other tables

我尝试使用上面的答案并将上面的关系选择语句的结果传递到临时表中,但没有成功。

有人可以帮我把我的第二张表整合到这个里面吗?

编辑: 要求提供完整代码:

USE [MyDatabase]
GO
ALTER PROCEDURE [dbo].[MergeTables]

@Selection int, 
@Table1Parameter udtt_1 READONLY,
@table2Parameter udtt_2 READONLY

AS

然后是您在上面看到的合并语句。

c# 代码只是使用数据表作为参数执行非查询。 c# 代码目前功能齐全。

【问题讨论】:

  • 你能提供完整的代码吗??比如@table2Parameter@selectionParameter等等……
  • 在过程中您已通过 - @Selection 并且在合并语句中您已使用 - @selectionParameter 变量。对吗??
  • 哎呀,对不起,这里打错了,它是同一个变量。下面代码上的名称应该是'selectionParameter'

标签: c# sql sql-server join merge


【解决方案1】:

这是修复,毕竟它确实涉及临时表:

USE [myDatabase]
GO

ALTER PROCEDURE [dbo].[MergeTables]
--declare parameters passed in from c#
--tables coming from c# are edited versions of the SQL tables.
@selectionParameter int, 
@Table1Parameter udtt_1 READONLY,
@table2Parameter udtt_2 READONLY

AS

--merge edits into table 1
MERGE INTO [Table1] AS target
USING @Table1Parameter AS source
ON target.ID = source.ID
AND target.Selection = @selectionParameter

WHEN NOT MATCHED BY TARGET
THEN INSERT (ID, Selection, Field1, Field2) VALUES (source.ID, source.Selection, source.Field1, source.Field2)
WHEN NOT MATCHED BY SOURCE AND target.Selection = @selectionParameter
THEN DELETE;

--define a temp table to hold table 2 editable rows
SELECT [Table2].* INTO T FROM [Table2]
INNER JOIN [Table1] ON [Table1].[ID] = [Table2].[ID] WHERE [Table1].[Selection] = @selectionParameter

--merge edits into temp table
MERGE INTO T AS target 
USING @table2Parameter AS source
ON target.ID = source.ID
WHEN NOT MATCHED BY TARGET
    THEN INSERT (ID, Field3, Field4) VALUES (source.ID, source.Field3, source.Field4)
WHEN NOT MATCHED BY SOURCE
    THEN DELETE;

--place edited or new rows into table 2
MERGE INTO [Table2] AS target 
USING T AS source
ON target.ID = source.ID
WHEN NOT MATCHED BY TARGET
    THEN INSERT (ID, Field3, Field4) VALUES (source.ID, source.Field3, source.Field4);

DROP TABLE T;

如果需要澄清,请告诉我。这非常复杂,花了我几个小时!希望它可以帮助遇到这种情况的其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-03
    • 2017-03-21
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 2014-10-28
    相关资源
    最近更新 更多