2012-06-13 6 views
25

Я немного модифицирую хранимую процедуру SQL Server 2005 для производительности, и я хотел бы быстро убедиться, что старые хранимые proc и новые возвращают одинаковые результаты (столбцы одинаковы, я хочу, чтобы строки были одинаковыми).SQL Server сравнивает результаты двух запросов, которые должны быть идентичными

Есть ли простой способ сделать это в SQL Server 2005?

ответ

38

вы можете использовать, кроме конструкции для соответствия между двумя запросами.

select * from (select * from query1) as query1 
except 
select * from (select * from query2) as query2 

EDIT:

Тогда обратный запрос, чтобы найти различия с Query2 как водителя:

select * from (select * from query2) as query2 
except 
select * from (select * from query1) as query1 
+6

А потом отменить его. – user1166147

+0

Да - @ user1166147. Спасибо за разъяснения. – jabs

+9

Обратите внимание, что это приведет к удалению дубликатов. Таким образом, если запрос возвращает 1 запись, а запрос возвращает две записи, идентичные друг другу, и к одной записи из запроса один, логика «except» возвращает нулевые строки. –

0

создать две таблицы темп, по одной для каждой процедуры. запустите процедуру для вставки строк в соответствующую таблицу.

затем выберите * из одного МИНУС выберите * от другой и визы Versa

+0

МИНУС это утверждение Oracle, КРОМЕ (как в вышеприведенных примерах) является T-SQL эквивалентно – flash

3
create table #OldProcResults (
    <Blah> 
) 

create table #NewProcResults (
    <Blih> 
) 

insert into #OldProcResults 
    exec MyOldProc 

insert into #NewProcResults 
    exec MyNewProc 

затем использовать ответ уколов, чтобы сравнить две таблицы.

1

Сохраненная процедура, приведенная ниже, будет сравнивать выходной результат из 2 хранимых процедур или 2 оператора. Ключевым моментом здесь является то, что SP не нужно знать структуру или схему результирующего набора, таким образом вы можете произвольно протестировать любой SP. Он будет возвращать 0 строк, если вывод одинаков. Это решение использует команду openrowset в SQL Server. Вот некоторые использования образца ХПА

DECLARE @SQL_SP1 VARCHAR(MAX) 
DECLARE @SQL_SP2 VARCHAR(MAX) 

-- Compare results of 2 Stored Procs 
SET @SQL_SP1 = 'EXEC SomeDB.dbo.[usp_GetWithTheProgram_OLD] 100, ''SomeParamX''' 
SET @SQL_SP1 = 'EXEC SomeDB.dbo.[usp_GetWithTheProgram_NEW] 50, ''SomeParamX''' 
EXEC utlCompareStatementResults @SQL_SP1, @SQL_SP2 

-- Compare just 2 SQL Statements 
SET @SQL_SP1 = 'SELECT * FROM SomeDB.dbo.Table1 WHERE CreatedOn > ''2016-05-08''' 
SET @SQL_SP1 = 'SELECT * FROM SomeDB.dbo.Table1 WHERE CreatedOn > ''2016-06-11''' 
EXEC utlCompareStatementResults @SQL_SP1, @SQL_SP2 

СП необходимы следующие предпосылки, которые не могут быть идеальными для производственной среды, но очень полезно для местных QA, Dev и тестирования. Он использует openrowset в коде.

EXEC sp_configure 'show advanced options', 1 
EXEC sp_configure 'ad hoc distributed queries', 1 
EXEC sp_serveroption @@SERVERNAME, 'DATA ACCESS', TRUE 

Вот код хранимой процедуры.

================================================================================== 
    --== SUMMARY utlCompareStatementResults 
    --== - requires sp_configure 'show advanced options', 1 
    --== - requires sp_configure 'ad hoc distributed queries', 1 
    --== - maybe requires EXEC sp_serveroption @@SERVERNAME, 'DATA ACCESS', TRUE 
    --== - requires the RecordSet Output to have Unique ColumnNames (no duplicate columns) 
    --== - requires references in straight SQL to be fully qualified [dbname].[schema].[objects] but not within an SP 
    --== - requires references SP call to be fully qualifed [dbname].[schema].[spname] but not objects with the SP 
    --== OUTPUT 
    --== Differences are returned 
    --== If there is no recordset returned, then theres no differences 
    --== However if you are comparing 2 empty recordsets, it doesn't mean anything 
    --== USAGE 
    --== DECLARE @SQL_SP1 VARCHAR(MAX) 
    --== DECLARE @SQL_SP2 VARCHAR(MAX) 
    --== -- Compare just 2 SQL Statements 
    --== SET @SQL_SP1 = 'SELECT * FROM SomeDB.dbo.Table1 WHERE CreatedOn > ''2016-05-08''' 
    --== SET @SQL_SP1 = 'SELECT * FROM SomeDB.dbo.Table1 WHERE CreatedOn > ''2016-06-11''' 
    --== EXEC utlCompareStatementResults @SQL_SP1, @SQL_SP2 
    --== 
    --== -- Compare results of 2 Stored Procs 
    --== SET @SQL_SP1 = 'EXEC SomeDB.dbo.[usp_GetWithTheProgram_OLD] 100, ''SomeParamX''' 
    --== SET @SQL_SP1 = 'EXEC SomeDB.dbo.[usp_GetWithTheProgram_NEW] 50, ''SomeParamX''' 
    --== EXEC utlCompareStatementResults @SQL_SP1, @SQL_SP2 
    --================================================================================== 
    CREATE PROCEDURE utlCompareStatementResults 
     @SQL_SP1 VARCHAR(MAX), 
     @SQL_SP2 VARCHAR(MAX) 
    AS 
    BEGIN 
     DECLARE @TABLE1 VARCHAR(200) 
     DECLARE @TABLE2 VARCHAR(200) 
     DECLARE @SQL_OPENROWSET VARCHAR(MAX) 
     DECLARE @CONNECTION VARCHAR(100) 

     SET @CONNECTION = 'server='[email protected]@SERVERNAME+';Trusted_Connection=yes' 

     SET @SQL_SP1 = REPLACE(@SQL_SP1, '''','''''') 
     SET @SQL_SP2 = REPLACE(@SQL_SP2, '''','''''') 

     SET @TABLE1 = '#' + SUBSTRING(CONVERT(VARCHAR(250),NEWID()), 1, 8) 
     SET @TABLE2 = '#' + SUBSTRING(CONVERT(VARCHAR(250),NEWID()), 1, 8) 

     SET @SQL_OPENROWSET = 
     'SELECT * ' + ' ' + 
     'INTO ' + @TABLE1 + ' ' + 
     'FROM OPENROWSET(''SQLNCLI'', ' + '''' + @CONNECTION + '''' + 
         ',''' + @SQL_SP1 +'''); ' + 
     'SELECT * ' + ' ' + 
     'INTO ' + @TABLE2 + ' ' + 
     'FROM OPENROWSET(''SQLNCLI'', ' + '''' + @CONNECTION + '''' + 
         ',''' + @SQL_SP2 +'''); ' + 
     '(SELECT * FROM ' + @TABLE1 + ' EXCEPT SELECT * FROM ' + @TABLE2 + ') ' + 
     ' UNION ALL ' + 
     '(SELECT * FROM ' + @TABLE2 + ' EXCEPT SELECT * FROM ' + @TABLE1 + '); ' + 
     'DROP TABLE ' + @TABLE1 + '; ' + 
     'DROP TABLE ' + @TABLE2 + '; ' 
     PRINT @SQL_OPENROWSET 
     EXEC (@SQL_OPENROWSET) 
     PRINT 'DifferenceCount: ' + CONVERT(VARCHAR(100), @@ROWCOUNT) 
    END 
Смежные вопросы