具有内部联接的SQL Server MERGE 2源/目标表

时间:2014-09-19 16:10:25

标签: c# sql sql-server join merge

我有一个包含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#代码目前完全正常运行。

1 个答案:

答案 0 :(得分:0)

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

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;

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