sql-server - inner - minus sql
SQL Server compara los resultados de dos consultas que deberÃan ser idénticas (4)
Estoy modificando ligeramente un procedimiento almacenado de SQL Server 2005 para mejorar el rendimiento, y me gustaría asegurarme rápidamente de que el antiguo proceso almacenado y el nuevo devuelvan exactamente los mismos resultados (las columnas son las mismas, quiero asegurarme de que las filas sean las mismas). mismo).
¿Hay una forma sencilla de hacer esto en el servidor SQL 2005?
Crea dos tablas temporales, una para cada procedimiento. ejecute el procedimiento para insertar filas en la tabla apropiada.
luego seleccione * de una MENOS seleccione * de la otra y visa-versa
El proceso almacenado a continuación comparará el conjunto de resultados de salida de 2 procedimientos almacenados, o 2 declaraciones. La clave aquí es que el SP no necesita conocer la estructura o el esquema del conjunto de resultados , por lo que puede probar arbitrariamente cualquier SP. Devolverá 0 filas si la salida es la misma. Esta solución utiliza el comando openrowset en SQL Server. Aquí hay algunos ejemplos de uso del proceso almacenado.
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
El SP requiere los siguientes requisitos previos, que pueden no ser ideales para un entorno de producción, pero muy útiles para los entornos locales de control de calidad, DEV y prueba. Utiliza openrowset en el código.
EXEC sp_configure ''show advanced options'', 1
EXEC sp_configure ''ad hoc distributed queries'', 1
EXEC sp_serveroption @@SERVERNAME, ''DATA ACCESS'', TRUE
Aquí está el código para el proc almacenado.
==================================================================================
--== 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=''+@@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
puede utilizar la construcción de excepción para que coincida entre las dos consultas.
select * from (select * from query1) as query1
except
select * from (select * from query2) as query2
EDITAR:
Luego invierta la consulta para encontrar las diferencias con query2 como controlador:
select * from (select * from query2) as query2
except
select * from (select * from query1) as query1
create table #OldProcResults (
<Blah>
)
create table #NewProcResults (
<Blih>
)
insert into #OldProcResults
exec MyOldProc
insert into #NewProcResults
exec MyNewProc
luego usa la respuesta de Jabs para comparar las dos tablas.