0

作为系统验证的一部分,我正在尝试比较两个查询之间的结果(下面的简化版本)

-- Reference query, writing the criteria myself as part of the verification process
SELECT p.Id, p.FullName
FROM Person p
WHERE -- some criteria

-- 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)

我发现了一个效果很好但仍然很重的hack。有没有更好的(写起来更简单)?

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    )
4

2 回答 2

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;
于 2013-03-20T15:33:16.183 回答
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 和此链接以获取更多信息

校验和

于 2013-03-20T23:06:41.250 回答