如何使用带有表值参数的存储过程来比较两个输入表

时间:2017-03-01 16:23:37

标签: sql-server stored-procedures table-valued-parameters

我正在尝试编写一个存储过程来计算两个输入表之间的差异。

存储过程用于计算两个表之间的差异(两个表具有相同的预定义表结构),存储过程将提供在将表1与表2进行比较时添加,删除或更新的记录。

示例:

  • 表1 New有3条记录:A,B和C
  • 表2有3条记录:B',C和D

B'表示对记录B中的一个或多个字段的更改

此存储过程调用的输出将为

A-addition  
B-update  
D-Removal  

我编写了一个查询来计算两个表之间的差异,但发现很难转换为存储过程。

表格结构:

X varchar (10)
Y int
Z datetime


SELECT 
    table1.*, ChangeType = 'Addition'
FROM 
    table1
WHERE
    NOT EXISTS (SELECT *
                FROM table2
                WHERE table1.x = table2.x)

UNION ALL

SELECT  
    table2.*, ChangeType = 'Removal'
FROM 
    table2
WHERE
    NOT EXISTS (SELECT *
                FROM table1
                WHERE table1.x = table2.x)

UNION ALL

SELECT   
    table1, ChangeType = 'Update'
FROM 
    table2
INNER JOIN
    table1 ON table1.x = table2.x
WHERE 
    table1.Y <> table2.Y OR table1.Z <> table2.Z

还请包括存储过程执行脚本。

2 个答案:

答案 0 :(得分:0)

我认为你正在寻找MERGE一句。您可以根据特定值将table1作为目标,将table2作为源,并决定在匹配的情况下该做什么:https://msdn.microsoft.com/en-us/library/bb510625.aspx

在你的情况下,它会是这样的:

MERGE table1 AS target  
USING table2 AS source (x, y, z)  
ON (target.x= source.x)  
WHEN MATCHED 
 --do something
WHEN NOT MATCHED BY TARGET  
 --do something different
WHEN NOT MATCHED BY SOURCE
 --something else

关于如何在SP中接收表作为参数,您需要按照以下步骤操作:

  1. 创建数据类型

    CREATE TYPE tableExample(X varchar(10), Y int, Z datetime)

  2. 将其传递给SP:

    CREATE PROC sp_mysp @ table1 tableExample,@ table2 tableExample AS ......

答案 1 :(得分:-1)

我更喜欢单次传递,使用case语句对操作进行分类。

CREATE PROCEDURE CompareTables
AS
BEGIN
  SELECT    ChangeType = CASE
                           WHEN table2.x IS NULL THEN
                             'Addition'
                           WHEN table1.x IS NULL THEN
                             'Removal'
                           WHEN table1.Y <> table2.Y
                                OR table1.Z <> table2.Z THEN
                             'Update'
                           ELSE
                             'No Change'
                         END,
            table1.*,
            table2.*
  FROM  table2
    FULL OUTER JOIN table1
      ON table1.x = table2.x
  WHERE table2.x IS NULL
        OR  table1.x IS NULL
        OR  NOT ( table1.Y = table2.Y
                  AND   table1.Z = table2.Z
                );
END;