2009-09-15 6 views
1

Je dois comparer TOUS les champs dans deux tableaux ... ils ont la même taille (quatre lignes) et ont le même nombre de colonnes (cinq colonnes). La logique que je cherche est ...Comparaison de deux tables de base de données

If (table 1 = table 2) 
do something 
Else 
do something else 

Dans SQL je l'ai écrit quelque chose comme ...

If (Select * from table 1 = select * from table 2) 
do something 
else 
do something else 

CE NE FONCTIONNE PAS !!!

J'ai essayé de faire EXCEPT et UNION ALL déclarations ... mais je n'ai pas besoin de connaître la ligne qui est différente ou même les valeurs qui sont différentes, j'ai juste besoin de savoir BOOLEAN 'oui' les tables sont différentes ou 'non ils ne sont pas.

Répondre

0


ALTER PROCEDURE dbo.CompareTables 
(
    @table1 VARCHAR(100), 
    @table2 VARCHAR(100), 
    @T1ColumnList VARCHAR(1000), 
    @T2ColumnList VARCHAR(1000) = '' 
) 
AS 
/* 
    Table1, Table2 are the tables or views to compare. 
    T1ColumnList is the list of columns to compare, from table1. 
    Just list them comma-separated, like in a GROUP BY clause. 
    If T2ColumnList is not specified, it is assumed to be the same 
    as T1ColumnList. Otherwise, list the columns of Table2 in 
    the same order as the columns in table1 that you wish to compare.

The result is all rows from either table that do NOT match 
the other table in all columns specified, along with which table that 
row is from. 

*/

DECLARE @SQL VARCHAR (8000)

SI @ t2ColumnList = '' SET @ T2ColumnList = @ T1ColumnList

SET @S QL = 'SELECT' '' + @ table1 + '' 'AS TableName,' + @ t1ColumnList + 'FROM' + @ Table1 + 'UNION ALL SELECT' '' + @ table2 + '' 'Comme TableName,' + @ t2ColumnList + 'à partir de' + @ Table2

SET @SQL = 'SELECT Max (TableName) comme TableName,' + @ t1ColumnList + 'à partir de (' + @SQL + ') A GROUP BY' + @ + t1ColumnList 'HAVING COUNT (*) = 1'

EXEC (@SQL)

+0

deviner un lien vaut 48 lignes de code;) –

0

Quelque chose comme cela devrait fonctionner, en utilisant Exist/non Existant - il est à vous comment interpréter soit obtenir ou non obtenir une rangée en arrière comme Vrai ou Faux. La syntaxe actuelle dépendra de la base de données. Ceci est Transact-SQL

Create table A 
(one int, two int, three int , four int) 

Create table B 
(one int, two int, three int, four int) 

insert A values (1,2,3,4) 
insert B values(1,2,3,4) 

select * from A a 
where exists (select 1 from B b where 
    a.one = b.one 
and a.two = b.two 
and a.three = b.three 
and a.four = b.four) 

un deux trois quatre


1

[révisée]

Voici comment vous feriez cela avec « SELECT .. .EXCEPT ... ":

IF not exists(select * 
       from MyTable 
       except select * 
       from MyOtherTable) 
and not exists(select * 
       from MyOtherTable 
       except select * 
       from MyTable) 
    PRINT 'They match' 
ELSE 
    PRINT 'They do not match' 

A Un peu plus rapide à écrire, sauf si vous avez besoin de comparer moins que toutes les colonnes. Cela nécessite quatre analyses de table, vous devez donc comparer et contraster les performances avec les stratégies UNION présentées. Dans mon expérience SELECT ... EXCEPT ... a tendance à fonctionner très rapidement - je devine parce que toute la comparaison des syndicats et des colonnes se produit en interne.

0

Si vous voulez comparer seulement quelques colonnes (ou tables avec 2-5 colonnes), vous pouvez utiliser ce FULL JOIN (non testé):

select  COUNT(*) AS UnmatchedRows 
from  table1 t1 
full join table2 t2 
     on t1.col1 = t2.col1 
     and t1.col2 = t2.col2 
     and t1.col3 = t2.col3 
     and t1.col4 = t2.col4 
     and t1.col5 = t2.col5 
where  COALESCE(t1.col1, t2.col1) IS NULL 

encore la solution référencée par Druide est très cool.

0

être fatigué d'écrire toutes les colonnes nouvelles chaque fois que j'ai développé le code Wiretaps.

"exec CompareTables table1, table2" fera le travail plus facile:

CREATE PROCEDURE [dbo].[CompareTables](@table1 varchar(100), 

@table2 Varchar(100)) 

AS 



-- Table1, Table2 are the tables or views to compare. 

-- The columns of both tables are acquired from the table definition 
-- ordered by the ordinal position 

-- The result is all rows from either table that do NOT match 

-- the other table in all columns specified, along with which table that 

-- row is from. 



declare @SQL varchar(8000); 
declare @T1ColumnList varchar(1000); 

SET @T1ColumnList = (
Select TOP 1 Stuff(
     (
     Select ',' + C.COLUMN_NAME 
     From INFORMATION_SCHEMA.COLUMNS As C 
     Where C.TABLE_SCHEMA = T.TABLE_SCHEMA 
      And C.TABLE_NAME = T.TABLE_NAME 
     Order By C.ORDINAL_POSITION 
     For Xml Path('') 
     ), 1, 1, '') As Columns 
From INFORMATION_SCHEMA.TABLES As T WHERE [email protected]) 
declare @T2ColumnList varchar(1000); 
SET @T2ColumnList = (
Select TOP 1 Stuff(
     (
     Select ',' + C.COLUMN_NAME 
     From INFORMATION_SCHEMA.COLUMNS As C 
     Where C.TABLE_SCHEMA = T.TABLE_SCHEMA 
      And C.TABLE_NAME = T.TABLE_NAME 
     Order By C.ORDINAL_POSITION 
     For Xml Path('') 
     ), 1, 1, '') As Columns 
From INFORMATION_SCHEMA.TABLES As T WHERE [email protected]) 



set @SQL = 'SELECT ''' + @table1 + ''' AS TableName, ' + @t1ColumnList + 

' FROM ' + @Table1 + ' UNION ALL SELECT ''' + @table2 + ''' As TableName, ' + 

@t2ColumnList + ' FROM ' + @Table2 



set @SQL = 'SELECT Max(TableName) as TableName, ' + @t1ColumnList + 

' FROM (' + @SQL + ') A GROUP BY ' + @t1ColumnList + 

' HAVING COUNT(*) = 1' 



exec (@SQL) 


GO 
Questions connexes