你试图实现的东西不是要在SQL Server中完成的。一个相当干净的方法是创建一个执行每个查询的代码,并通过元数据和值来比较两个结果数据集。
我不建议您使用以下方法。
出于测试目的我建立这个存储过程:
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'SP_CompareQueryResults')
DROP PROCEDURE SP_CompareQueryResults
GO
CREATE PROCEDURE SP_CompareQueryResults
(
@sql1 NVARCHAR(4000)
, @sql2 NVARCHAR(4000)
)
AS
BEGIN
DECLARE @q1 NVARCHAR(MAX) = @sql1
, @q2 NVARCHAR(MAX) = @sql2
IF OBJECT_ID('tempdb..##q1') IS NOT NULL
DROP TABLE ##q1
IF OBJECT_ID('tempdb..##q2') IS NOT NULL
DROP TABLE ##q2
SET @q1 = 'SELECT * INTO ##q1 FROM (' + @q1 + ') r'
SET @q2 = 'SELECT * INTO ##q2 FROM (' + @q2 + ') r'
BEGIN TRY
EXEC (@q1)
EXEC (@q2)
END TRY
BEGIN CATCH
SELECT 'One of the source queries are not valid.'
RETURN
END CATCH
DECLARE @r NVARCHAR(MAX)
SELECT @r = COALESCE(@r + ', ', ' ') + COLUMN_NAME
FROM (
SELECT COLUMN_NAME
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '##q1'
INTERSECT
SELECT COLUMN_NAME
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '##q2'
) r
SET @r = 'SELECT 1 as SourceQuery, * FROM (SELECT ' + @r + ' FROM ##q1 EXCEPT SELECT' + @r + ' FROM ##q2) r'
+ ' UNION ALL SELECT 2 as SourceQuery, * FROM (SELECT ' + @r + ' FROM ##q2 EXCEPT SELECT' + @r + ' FROM ##q1) r'
BEGIN TRY
EXEC(@r)
END TRY
BEGIN CATCH
SELECT 'Queries have not matching metadata.'
RETURN
END CATCH
IF OBJECT_ID('tempdb..##q1') IS NOT NULL
DROP TABLE ##q1
IF OBJECT_ID('tempdb..##q2') IS NOT NULL
DROP TABLE ##q2
END
GO
它发现列与来自两个查询相同的名称和比较每个查询的结果的,返回从查询1行不包括在查询2和其他方式。
比方说,你有两个查询与结果如下:
和另一个问题:
正如你可以看到第二个查询有一个附加列,列不是以相同的顺序,只有一个元组在两个查询中。
执行上述SP是这样的:
EXEC SP_CompareQueryResults
@sql1 = N'
SELECT 1 AS ID
, ''test'' AS Value
, CAST(1 as BIT) AS Valid
UNION ALL
SELECT 2, ''test2'', 0',
@sql2 = N'
SELECT 1 AS ID
, CAST(1 as BIT) AS Valid
, ''test'' AS Value
, ''test'' AS AnotherValue
UNION ALL
SELECT 2, 1, ''test2'', ''whatever'''
让您没有从两个查询匹配的元组:
如果这两个查询产生相同的结果,该SP_CompareQueryResults将不会返回任何行,所以你可以说他们具有匹配名称的列相同的值。如果两个查询都没有结果行,则会发生同样的情况,从而导致误报。您可以根据需要调整上述步骤。
请勿在生产环境中使用此代码,因为它可能是SQL注入的,我没有对此进行测试。一般情况下要避免动态sql,如果没有必要如上所述,尝试编写例如c#代码是sql注入安全并比较结果。
尝试查找EXCEPT运算符。它可能会帮助你 –
简单*不*使用* *和*不*取决于任意的列顺序。编写一个适当的语句,其子查询明确指定要返回的列 –
您能否确保来自变量的查询返回相同的列?列名是否相同? –