你試圖實現的東西不是要在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運算符。它可能會幫助你 –
簡單*不*使用* *和*不*取決於任意的列順序。編寫一個適當的語句,其子查詢明確指定要返回的列 –
您能否確保來自變量的查詢返回相同的列?列名是否相同? –