あなたが達成しようとするのは、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
をそれが両方のクエリからの同じ名前の列を検索し、クエリ結果の各々とを比較し、クエリ2に含まれていないクエリ1から行を返すと他の方法で。
あなたは次のような結果との2つのクエリがあるとしましょう:あなたは列があり、2番目のクエリは、追加の列を持って見ることができるように
:
と別のものを同じ順序ではなく、両方のクエリに1つのタプルしかありません。このような上記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演算子を試してみてください。 –
* '*'を使わないで*任意の列の順序に依存しないでください。サブクエリが返すカラムを明示的に指定する適切なステートメントを記述してください –
変数からのクエリが同じカラムを返すことを保証できますか?列名は同じですか? –