it-swarm.com.de

Einfachste Möglichkeit, zwei Tabellenschemas in SQL Server 2008 zu unterscheiden?

Ich muss Überprüfungen zwischen einer Entwicklungs- und Release-Datenbank durchführen und dies manuell tun, was langsam und nicht 100% zuverlässig ist (ich überprüfe nur die Tabellen).

Gibt es eine schnelle und einfache Möglichkeit, Tabellenschemas automatisch zu vergleichen? Vielleicht sogar eine Funktion, die dies direkt in den SQL-Server integriert?

Edit: Ich vergleiche nur die Struktur. Danke, dass Sie mich darauf aufmerksam gemacht haben.

26
sooprise

Ich bin ein Fan von SQL DBDiff , einem Open-Source-Tool, mit dem Sie Tabellen, Ansichten, Funktionen, Benutzer usw. von zwei Instanzen von SQL Server-Datenbanken vergleichen und ein Änderungsskript zwischen der Quelle und generieren können Zieldatenbanken.

22

Es gibt einige kommerzielle Produkte, die dies tun. Visual Studio 2010 Premium Edition kann Schemas vergleichen.

Einige andere:
http://www.red-gate.com/products/SQL_Compare/index.htm
http://www.apexsql.com/sql_tools_diff.aspx

10
Jeremy Elbourn

Ich bin etwas spät dran ... aber dieses Skript, das ich gemacht habe, hat gut für mich funktioniert. Bei Bedarf funktioniert das auch über verbundene Server.

use master
go

DECLARE @Server1 VARCHAR(100) ='[CARNYSQLTEST1].'; --include a dot at the end
DECLARE @DB1 VARCHAR(100) = '[ZipCrim]';
DECLARE @Table1 VARCHAR(100) = 'IntAction';

DECLARE @Server2 VARCHAR(100) ='[CARNYSQLDEV].'; --include a dot at the end
DECLARE @DB2 VARCHAR(100) = '[ZipCrim]';
DECLARE @Table2 VARCHAR(100) = 'IntAction';

DECLARE @SQL NVARCHAR(MAX);


SET @SQL = 
'
SELECT Table1.ServerName,
       Table1.DBName,
       Table1.SchemaName,
       Table1.TableName,
       Table1.ColumnName,
       Table1.name DataType,
       Table1.Length,
       Table1.Precision,
       Table1.Scale,
       Table1.Is_Identity,
       Table1.Is_Nullable,
       Table2.ServerName,
       Table2.DBName,
       Table2.SchemaName,
       Table2.TableName,
       Table2.ColumnName,
       Table2.name DataType,
       Table2.Length,
       Table2.Precision,
       Table2.Scale,
       Table2.Is_Identity,
       Table2.Is_Nullable
FROM   
    (SELECT ''' + @Server1 + ''' ServerName, 
           ''' + @DB1 + ''' DbName,
           SCHEMA_NAME(t.schema_id) SchemaName,
           t.Name TableName,
           c.Name ColumnName,
           st.Name,
           c.Max_Length Length,
           c.Precision,
           c.Scale,
           c.Is_Identity,
           c.Is_Nullable
    FROM   ' + @Server1 + @DB1 + '.sys.tables t
           INNER JOIN ' + @Server1 + @DB1 + '.sys.columns c ON t.Object_ID = c.Object_ID
           INNER JOIN sys.types st ON St.system_type_id = c.System_Type_id AND st.user_type_id = c.user_type_id
    WHERE  t.Name = ''' + @Table1 + ''') Table1 
    FULL OUTER JOIN
    (SELECT ''' + @Server2 + ''' ServerName, 
           ''' + @DB2 + ''' DbName,
           SCHEMA_NAME(t.schema_id) SchemaName,
           t.name TableName,
           c.name ColumnName,
           st.Name,
           c.max_length Length,
           c.Precision,
           c.Scale,
           c.Is_Identity,
           c.Is_Nullable
    FROM   ' + @Server2 + @DB2 + '.sys.tables t
           INNER JOIN ' + @Server2 + @DB2 + '.sys.columns c ON t.Object_ID = c.Object_ID
           INNER JOIN sys.types st ON St.system_type_id = c.System_Type_id AND st.user_type_id = c.user_type_id
    WHERE  t.Name = ''' + @Table2 + ''') Table2
    ON Table1.ColumnName = Table2.ColumnName
ORDER BY CASE WHEN Table1.ColumnName IS NULL THEN 2 ELSE 1 END, Table1.ColumnName
'

EXEC sp_executesql @SQL
7
BD.

Daten oder Struktur oder beides? Versuchen Sie es mit RedGate SQL-Vergleich oder Datenvergleich. Beide haben kostenlose Testversionen und sind großartig.

http://www.red-gate.com/products/SQL_Compare/index.htm

http://www.red-gate.com/products/SQL_Data_Compare/index.htm

7
Kuberchaun

Soo,

Googled dies:

für Strukturen :

siehe auch : </ s>

Die Links meiner vorherigen Antworten funktionieren aus irgendeinem Grund nicht mehr, daher folgt eine weitere Antwort von TechNet :

DECLARE @Sourcedb sysname 
DECLARE @Destdb sysname 
DECLARE @Tablename sysname 
DECLARE @SQL varchar(max) 

SELECT @Sourcedb = '<<SourceDatabaseName>>' 
SELECT @Destdb   = '<<DestinationDatabaseName>>' 
SELECT @Tablename = '<<Tablename>>' --  '%' for all tables 

SELECT @SQL = ' SELECT Tablename  = ISNULL(Source.tablename,Destination.tablename) 
                      ,ColumnName = ISNULL(Source.Columnname,Destination.Columnname) 
                      ,Source.Datatype 
                      ,Source.Length 
                      ,Source.precision 
                      ,Destination.Datatype 
                      ,Destination.Length 
                      ,Destination.precision 
                      ,[Column]  = 
                       Case  
                       When Source.Columnname IS NULL then ''Column Missing in the Source'' 
                       When Destination.Columnname IS NULL then ''Column Missing in the Destination'' 
                       ELSE '''' 
                       end 
                      ,DataType = CASE WHEN Source.Columnname IS NOT NULL  
                                        AND Destination.Columnname IS NOT NULL  
                                        AND Source.Datatype <> Destination.Datatype THEN ''Data Type mismatch''  
                                  END 
                      ,Length   = CASE WHEN Source.Columnname IS NOT NULL  
                                        AND Destination.Columnname IS NOT NULL  
                                        AND Source.Length <> Destination.Length THEN ''Length mismatch''  
                                  END 
                      ,Precision = CASE WHEN Source.Columnname IS NOT NULL  
                                        AND Destination.Columnname IS NOT NULL 
                                        AND Source.precision <> Destination.precision THEN ''precision mismatch'' 
                                    END 
                      ,Collation = CASE WHEN Source.Columnname IS NOT NULL  
                                        AND Destination.Columnname IS NOT NULL 
                                        AND ISNULL(Source.collation_name,'''') <> ISNULL(Destination.collation_name,'''') THEN ''Collation mismatch'' 
                                        END 

   FROM  
 ( 
 SELECT Tablename  = so.name  
      , Columnname = sc.name 
      , DataType   = St.name 
      , Length     = Sc.max_length 
      , precision  = Sc.precision 
      , collation_name = Sc.collation_name 
  FROM ' + @Sourcedb + '.SYS.objects So 
  JOIN ' + @Sourcedb + '.SYS.columns Sc 
    ON So.object_id = Sc.object_id 
  JOIN ' + @Sourcedb + '.SYS.types St 
    ON Sc.system_type_id = St.system_type_id 
   AND Sc.user_type_id   = St.user_type_id 
 WHERE SO.TYPE =''U'' 
   AND SO.Name like ''' + @Tablename + ''' 
  ) Source 
 FULL OUTER JOIN 
 ( 
  SELECT Tablename  = so.name  
      , Columnname = sc.name 
      , DataType   = St.name 
      , Length     = Sc.max_length 
      , precision  = Sc.precision 
      , collation_name = Sc.collation_name 
  FROM ' + @Destdb + '.SYS.objects So 
  JOIN ' + @Destdb + '.SYS.columns Sc 
    ON So.object_id = Sc.object_id 
  JOIN ' + @Destdb + '.SYS.types St 
    ON Sc.system_type_id = St.system_type_id 
   AND Sc.user_type_id   = St.user_type_id 
WHERE SO.TYPE =''U'' 
  AND SO.Name like ''' + @Tablename + ''' 
 ) Destination  
 ON source.tablename = Destination.Tablename  
 AND source.Columnname = Destination.Columnname ' 

EXEC (@Sql)
4
pageman

Für eine kostenlose Lösung können Sie SQL Server Managements Objects verwenden, um das DDL-Skript für jede Tabelle, Ansicht, Index, SP, UDF usw. ausgeben WinMerge .

2
RedFilter

sie können einen Blick auf http://cdttools.com/2011/10/sql-diff-erence/ werfen. Dies ist eine kostengünstige Alternative. Das Schema wechselt zwischen zwei Datenbanken und informiert Sie über Änderungen. Sie können dann SQL Mgmt Studio verwenden, um "Script-> As Alter" zum Erstellen von Änderungsskripts zu erstellen. (Vorbehalt: Ich habe es geschrieben)

1
Chris Turner

Wenn sich zwei Tabellen in derselben Datenbank befinden, können Sie diese Abfrage verwenden

select c2.table_name,c2.COLUMN_NAME
from [INFORMATION_SCHEMA].[COLUMNS] c2
where table_name='table1'
and c2.COLUMN_NAME not in (select column_name 
    from [INFORMATION_SCHEMA].[COLUMNS] 
    where table_name='table1')
1
thejustv

Etwas von BD.'s Abfrage geändert , alles Guthaben geht an ihn. (SCHEMA_NAME(schema_id) in sys.schemas join geändert, da SCHEMA_NAME(schema_id) mit dem aktuellen db-Kontext arbeitet, der master ist, die Sortierung geändert und die Spaltennamen geändert und die Statusspalte hinzugefügt hat.)

USE master
GO

DECLARE
    @Server1 VARCHAR(100) = 'Server1.', -- don't forget to include a dot at the end
    @Server2 VARCHAR(100) = 'Server2.', -- don't forget to include a dot at the end
    @DB1 VARCHAR(100) = 'Database1',
    @DB2 VARCHAR(100) = 'Database2'

DECLARE @SQL NVARCHAR(MAX);

SET @SQL = '
SELECT
    CASE
        WHEN s1.[Column] IS NOT NULL
            AND s2.[Column] IS NULL
            THEN ''New''
        WHEN s1.[Column] IS NULL
            AND s2.[Column] IS NOT NULL
            THEN ''Deleted''
        WHEN s1.[Column] IS NOT NULL
            AND s2.[Column] IS NOT NULL
            AND (s1.[Type] <> s2.[Type]
                OR s1.[Length] <> s2.[Length]
                OR s1.[Precision] <> s2.[Precision]
                OR s1.Scale <> s2.Scale
                OR s1.IsNullable <> s2.IsNullable
                OR s1.IsIdentity <> s2.IsIdentity
                OR s1.IdentitySeed <> s2.IdentitySeed
                OR s1.IdentityIncrement <> s2.IdentityIncrement
                OR s1.DefaultValue <> s2.DefaultValue)
            THEN ''Changed''
        ELSE ''Identical''
    END [Status],
    s1.[Database],
    s1.[Schema],
    s1.[Table],
    s1.[Column],
    s1.[Type],
    s1.IsCharType,
    s1.[Length],
    s1.[Precision],
    s1.Scale,
    s1.IsNullable,
    s1.IsIdentity,
    s1.IdentitySeed,
    s1.IdentityIncrement,
    s1.DefaultValue,
    s1.[Order],
    s2.[Database],
    s2.[Schema],
    s2.[Table],
    s2.[Column],
    s2.[Type],
    s2.IsCharType,
    s2.[Length],
    s2.[Precision],
    s2.Scale,
    s2.IsNullable,
    s2.IsIdentity,
    s2.IdentitySeed,
    s2.IdentityIncrement,
    s2.DefaultValue,
    s2.[Order]
FROM (
    SELECT
        ''' + @DB1 + ''' AS [Database],
        s.name AS [Schema],
        t.name AS [Table],
        c.name AS [Column],
        tp.name AS [Type],
        CASE 
            WHEN tp.collation_name IS NOT NULL
                THEN 1
            ELSE 0
        END AS IsCharType,
        CASE
            WHEN c.max_length = -1
                THEN ''MAX''
            ELSE CAST(c.max_length AS VARCHAR(4))
        END AS [Length],
        c.[precision],
        c.scale,
        c.is_nullable AS IsNullable,
        c.is_identity AS IsIdentity,
        CAST(ISNULL(ic.seed_value, 0) AS INT) AS IdentitySeed,
        CAST(ISNULL(ic.increment_value, 0) AS INT) AS IdentityIncrement,
        dc.definition AS DefaultValue,
        c.column_id AS [Order]
    FROM ' + @Server1 + @DB1 + '.sys.tables t
        INNER JOIN ' + @Server1 + @DB1 + '.sys.schemas s ON s.schema_id = t.schema_id
        INNER JOIN ' + @Server1 + @DB1 + '.sys.columns c ON c.object_id = t.object_id
        INNER JOIN ' + @Server1 + @DB1 + '.sys.types tp ON tp.system_type_id = c.system_type_id
        LEFT OUTER JOIN ' + @Server1 + @DB1 + '.sys.identity_columns ic ON ic.object_id = t.object_id AND ic.name = c.name
        LEFT OUTER JOIN ' + @Server1 + @DB1 + '.sys.default_constraints dc ON dc.object_id = c.default_object_id
    ) s1
FULL OUTER JOIN (
    SELECT
        ''' + @DB2 + ''' AS [Database],
        s.name AS [Schema],
        t.name AS [Table],
        c.name AS [Column],
        tp.name AS [Type],
        CASE 
            WHEN tp.collation_name IS NOT NULL
                THEN 1
            ELSE 0
        END AS IsCharType,
        CASE
            WHEN c.max_length = -1
                THEN ''MAX''
            ELSE CAST(c.max_length AS VARCHAR(4))
        END AS [Length],
        c.[precision],
        c.scale,
        c.is_nullable AS IsNullable,
        c.is_identity AS IsIdentity,
        CAST(ISNULL(ic.seed_value, 0) AS INT) AS IdentitySeed,
        CAST(ISNULL(ic.increment_value, 0) AS INT) AS IdentityIncrement,
        dc.definition AS DefaultValue,
        c.column_id AS [Order]
    FROM ' + @Server2 + @DB2 + '.sys.tables t
        INNER JOIN ' + @Server2 + @DB2 + '.sys.schemas s ON s.schema_id = t.schema_id
        INNER JOIN ' + @Server2 + @DB2 + '.sys.columns c ON c.object_id = t.object_id
        INNER JOIN ' + @Server2 + @DB2 + '.sys.types tp ON tp.system_type_id = c.system_type_id
        LEFT OUTER JOIN ' + @Server2 + @DB2 + '.sys.identity_columns ic ON ic.object_id = t.object_id AND ic.name = c.name
        LEFT OUTER JOIN ' + @Server2 + @DB2 + '.sys.default_constraints dc ON dc.object_id = c.default_object_id
    ) s2
    ON s2.[Schema] = s1.[Schema]
    AND s2.[Table] = s1.[Table]
    AND s2.[Column] = s1.[Column]   
ORDER BY
    CASE WHEN s1.[Database] IS NULL THEN s2.[Database] ELSE s1.[Database] END,
    CASE WHEN s1.[Schema] IS NULL THEN s2.[Schema] ELSE s1.[Schema] END,
    CASE WHEN s1.[Table] IS NULL THEN s2.[Table] ELSE s1.[Table] END,
    CASE WHEN s1.[Order] IS NULL THEN s2.[Order] ELSE s1.[Order] END
'

EXEC sp_executesql @SQL
1
mehyaa

Sie können die SQL Management Studio-Tools zum "Generieren von Skripts" aus beiden Datenbanken verwenden. Verwenden Sie dann Ihr bevorzugtes Textvergleichstool, um Unterschiede festzustellen. 

In früheren Zeiten funktionierte dies hervorragend, aber in SQL 2005 wurde der Code zum Generieren von Skripts geändert, und die Objekte wurden nicht mehr in derselben Reihenfolge erstellt, sodass der Textvergleich weniger nützlich ist. Ich habe dies nicht in neueren Versionen von SQL getestet, daher wurde es möglicherweise behoben. Sie können auch versuchen, http://exportsqlscript.codeplex.com/ die ich mit gutem Erfolg verwendet habe, um die DDL als Skripts für die Quellcodeverwaltung und zum Vergleichen von Versionen auszugeben.

Verweise:

0
Michael Levy