2010-10-18 9 views
20

मुझे एक विकास और डेटाबेस के बीच जांच करना है और इसे मैन्युअल रूप से करना है, जो धीमा है और 100% विश्वसनीय नहीं है (मैं केवल टेबल का निरीक्षण करता हूं)।एसक्यूएल सर्वर 2008 में दो टेबल स्कीमा को डिफ करने का सबसे आसान तरीका?

क्या टेबल स्कीमा की तुलना करने के लिए स्वचालित रूप से एक त्वरित और आसान तरीका है? हो सकता है कि एक सुविधा भी जो SQL सर्वर में सही ढंग से बनाई गई हो?

संपादित करें: मैं केवल संरचना की तुलना कर रहा हूं, इसे इंगित करने के लिए धन्यवाद।

+0

नोट: ओपी संरचना, नहीं डेटा के बारे में बात कर रहा है। – RedFilter

+1

@RedFilter: यह स्पष्ट करने के लिए प्रश्न संपादित किया गया कि, वास्तव में यह –

+0

भ्रमित कर रहा था बेशक यह मदद करेगा यदि आपने परिवर्तनों को स्क्रिप्ट किया है और सॉफ़्टवेयर के उस संस्करण के लिए शेष कोड के साथ उन्हें स्थानांतरित करने के लिए स्रोत नियंत्रण में रखा है। तो आपको यह सब कुछ करने की ज़रूरत नहीं होगी (और हो सकता है कि गलती से प्रोड के लिए अभी तक तैयार न हो।) – HLGEM

उत्तर

21

मैं SQL DBDiff के एक प्रशंसक है, जो एक खुला स्रोत उपकरण आपको टेबल, विचार, काम करता है, उपयोगकर्ताओं, आदि एसक्यूएल सर्वर डेटाबेस के दो उदाहरणों की तुलना करने के लिए उपयोग कर सकते हैं कर रहा हूँ और स्रोत और गंतव्य डेटाबेस के बीच एक परिवर्तन स्क्रिप्ट उत्पन्न करें।

+0

diff उपकरण थोड़ा उपपर है, मुझे स्रोत और गंतव्य के बीच संरचनाओं में स्पष्ट मतभेद थे और इससे उन्हें बिल्कुल हाइलाइट नहीं किया गया। यह कहकर, यह कुछ पाया, बस सभी नहीं .. – Eric

6

डेटा या संरचना या दोनों? RedGate sql तुलना या डेटा तुलना करने का प्रयास करें। दोनों के पास स्वतंत्र परीक्षण हैं और वे बहुत ही अच्छे हैं।

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

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

+0

बस संरचना। क्या उस $ 400 जानवर का एक मुफ्त संस्करण है? – sooprise

+0

red_gate के उपकरण से बेहतर कुछ भी मुफ्त संस्करण नहीं है। यह कुछ है जो आपको पैसे खर्च करना चाहिए। – HLGEM

+0

मैंने अभी डीबी डिफ डाउनलोड किया है और यह मेरे द्वारा किए गए सरल कार्यों के लिए काम करता है। हालांकि मैं भविष्य में लाल गेट को दिमाग में रखूंगा। – sooprise

2

एक नि: शुल्क समाधान के लिए, आप SQL Server Managements Objects उत्पादन के लिए DDL स्क्रिप्ट हर तालिका, देखने के लिए, सूचकांक, सपा, यूडीएफ, आदि तो फिर तुम तुलना कर सकते हैं के लिए या तो कोड में, या WinMerge की तरह एक diff उपकरण का उपयोग कर उपयोग कर सकते हैं,।

1

सू,

इस Google पर:

for structures:

see also:

मेरे पिछले जवाब 'लिंक किसी कारण से अब और काम नहीं करता है, इसलिए यहाँ 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) 
0

आप एसक्यूएल प्रबंधन स्टूडियो उपकरणों का उपयोग कर सकते हैं दोनों डेटाबेस से "स्क्रिप्ट उत्पन्न करने के लिए"। फिर किसी भी अंतर को देखने के लिए अपने पसंदीदा टेक्स्ट तुलना टूल का उपयोग करें।

पुराने दिनों में, यह बहुत अच्छा काम करता था, लेकिन SQL 2005 में जेनरेट स्क्रिप्ट कोड बदल गया और ऑब्जेक्ट्स एक ही क्रम में नहीं बनाए गए थे, इसलिए टेक्स्ट तुलना कम उपयोगी है। मैंने एसक्यूएल के हाल के संस्करणों में इसका परीक्षण नहीं किया है, इसलिए यह तय हो सकता है। आप http://exportsqlscript.codeplex.com/ भी कोशिश कर सकते हैं जिसे मैंने डीडीएल को स्रोत कोड नियंत्रण और संस्करणों की तुलना करने के लिए स्क्रिप्ट के रूप में आउटपुट करने के लिए अच्छी सफलता के साथ उपयोग किया है।

संदर्भ:

+0

और निश्चित रूप से, मेरा पसंदीदा टेक्स्ट तुलना टूल http://www.scootersoftware.com/ –

+1

से तुलना से परे है, मैंने उस सटीक चीज़ की कोशिश की (स्क्रिप्ट उत्पन्न करना, और मैं तुलना से परे भी इस्तेमाल किया)। दुर्भाग्यवश, आपके पोस्ट स्टेटस के रूप में, यह ऑर्डरिंग के कारण असफल रहा ... – sooprise

+0

http://exportsqlscript.codeplex.com/ इस समस्या को ठीक करता है। और, जैसा कि मैंने इसे माइक्रोसॉफ्ट के लिए एक बग के रूप में बताया और लॉग में किसी ने कहा "यह अगली रिलीज में तय है"। मैंने माइक्रोसॉफ्ट से फिक्स कभी नहीं देखा। –

1

आप http://cdttools.com/2011/10/sql-diff-erence/ अपनी एक कम लागत विकल्प पर एक नज़र ले जा सकते हैं, दो डेटाबेस के बीच स्कीमा चलना और आपको बता देंगे क्या बदला हुआ। फिर आप स्क्रिप्ट स्क्रिप्ट बनाने के लिए "स्क्रिप्ट-> एल्टर के रूप में" उत्पन्न करने के लिए SQL Mgmt स्टूडियो का उपयोग कर सकते हैं। (चेतावनी: मैं इसे लिखा था)

0

एक ही डेटाबेस में दो तालिकाओं, तो आप इस क्वेरी

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') 
5

उपयोग कर सकते हैं मैं एक छोटे से खेल के लिए देर हो रही है ... लेकिन इस स्क्रिप्ट मैंने अच्छी तरह से काम किया है मेरे लिए। यदि आवश्यक हो तो यह लिंक किए गए सर्वरों पर भी काम करेगा।

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 
1

BD.'s query का एक सा संशोधित, सारा श्रेय उसे जाता है। (Sys.schemas में बदला गया SCHEMA_NAME(schema_id) में शामिल होने क्योंकि वर्तमान डाटाबेस संदर्भ में जो master है, साथ SCHEMA_NAME(schema_id) काम करता है छँटाई बदल गया है और स्तंभ नाम बदल गया है और स्थिति कॉलम जोड़ा)

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 
संबंधित मुद्दे