2013-03-20 67 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

相關問題