2013-03-20 63 views
0

由于系统验证的一部分,我想比较两个查询之间的结果(如下简化版本)有没有实现T-SQL(两个请求之间的差值)

-- Reference query, writing the criteria myself as part of the verification process 
SELECT p.Id, p.FullName 
FROM Person p 
WHERE -- some criteria 
逻辑XOR一个聪明的办法

而且

-- Data Query, simply reading what my system under tests thinks of the same criteria 
SELECT p.Id, p.FullName 
FROM Person p 
    RIGHT JOIN PersonsThatMatchCriteria pmc ON ... 

我想,以确保他们返回德相同的结果,并且如果没有,我想显示它们进行分析。

((REFERENCE QUERY) 
EXCEPT 
(DATA QUERY)) 
    UNION 
((DATA QUERY) 
EXCEPT 
(REFERENCE QUERY)) 

由于我的流程在工具和自动化方面很差,我主要是通过手工输入这些请求。我讨厌重新键入/复制粘贴查询两次,因为它很容易出错。

所以,问题很简单:有一个简单的语法(或简单的工具),让我写类似

(REFERENCE QUERY) 
    XOR 
(DATA QUERY) 

我发现效果很好,但仍然是沉重的一劈。有没有更好的(写起来更简单)?

DECLARE @ShouldBeIncluded TABLE(Id INT); INSERT INTO @ShouldBeIncluded 
    SELECT p.Id, p.FullName 
    FROM Person p 
    WHERE ... 

DECLARE @ActuallyIncluded TABLE(Id INT); INSERT INTO @ActuallyIncluded 
    SELECT p.Id, p.FullName 
    FROM Person p 
     RIGHT J 

SELECT p.Id, p.FullName 
FROM Person p 
WHERE p.Id IN (  SELECT Id FROM @ActuallyIncluded 
        EXCEPT SELECT Id FROM @ShouldBeIncluded ) 
    OR p.Id IN (   SELECT Id FROM @ShouldBeIncluded 
        EXCEPT SELECT Id FROM @ActuallyIncluded ) 
+1

我通常完全外连接。 DBA网站上的相关问题[轻松显示两个表或查询之间不同的行](http://dba.stackexchange.com/q/12580) – 2013-03-20 15:36:04

回答

2

你可以使用一个CTE:

WITH ComplexQuery1(Col1, Col2) AS (
SELECT Col1, Col2 
FROM ... 
), 
ComplexQuery2(Col1, Col2) AS (
SELECT Col1, Col2 
FROM ... 
), 
Except1(Col1, Col2) AS(
SELECT * FROM ComplexQuery1 
EXCEPT 
SELECT * FROM ComplexQuery2 
), 
Except2(Col1, Col2) AS(
SELECT * FROM ComplexQuery2 
EXCEPT 
SELECT * FROM ComplexQuery1 
) 
SELECT * FROM Except1 
UNION ALL 
SELECT * FROM Except2; 
0

据我了解你的需要是要显示的不是由实际的查询,并返回从没有实际的查询任何结果的任何预期结果预期。

我会使用两个表,第一个表包含期望的数据并且包含跨所有intrest列的校验和值,第二个表是查询在实际系统上的结果,并且应该包含校验和列在实际查询执行后更新。

评估下面的例子,看看它是否适合你的需要。

declare @lt_ExpectedResults table (lER_PersonName varchar(20), lER_PersonStuff varchar(20), lER_Chksum bigint) 
    Insert @lt_ExpectedResults (lER_PersonName, lER_PersonStuff) 
    Values 
    ('Bubba1','Stuf1'), 
    ('Bubba2','stuff2') 
    Update @lt_ExpectedResults set lER_Chksum = CHECKSUM(*) 

    declare @lt_ActualResults table (lAR_PersonName varchar(20), lAR_PersonStuff varchar(20), lAR_Chksum bigint) 
    Insert @lt_ActualResults (lAR_PersonName, lAR_PersonStuff) 
    Values 
    ('Bubba1','Stuf1'), 
    ('Bubba3','stuff2') 
    Update @lt_ActualResults set lAR_Chksum = CHECKSUM(*) 

    select * from @lt_ExpectedResults 
    select * from @lt_ActualResults 

    Select * from @lt_ExpectedResults 
    full outer join @lt_ActualResults 
    on lAR_Chksum = lER_Chksum 
    where lAR_Chksum is NULL or lER_Chksum is NULL 

您应该知道有些情况下,CHECKSUM值将与完全相同的源数据相同。审查的StackOverflow而这个链接获取更多信息

CheckSum

相关问题