開発データベースとリリースデータベースの間でチェックを行う必要があり、手動で行う必要がありますが、これは遅く、100%の信頼性がありません(テーブルを視覚的に検査するだけです)。
テーブルスキーマを自動的に比較する迅速で簡単な方法はありますか?たぶん、これがSQLサーバーに組み込まれている機能でさえありますか?
編集:私は構造のみを比較しています、これを指摘してくれてありがとう。
私は SQL DBDiff のファンです。これは、SQL Serverデータベースの2つのインスタンスのテーブル、ビュー、関数、ユーザーなどを比較し、その間の変更スクリプトを生成するために使用できるオープンソースツールですソースおよび宛先データベース。
これを行う商用製品がいくつかあります。 Visual Studio 2010 Premium Editionはスキーマを比較できます。
他の何人か:
http://www.red-gate.com/products/SQL_Compare/index.htm
http://www.apexsql.com/sql_tools_diff.aspx
私はゲームに少し遅れています...しかし、私が作ったこのスクリプトは私にとってうまく機能しました。必要に応じて、リンクサーバーでも機能します。
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
データまたは構造、あるいはその両方? RedGate SQL比較またはデータ比較を試してください。どちらも無料試用版があり、素晴らしいです。
スー、
これをググってみた:
構造の場合 :
参照 :
以前の回答のリンクが何らかの理由で機能しなくなったため、 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)
無料のソリューションでは、 SQL Server Managements Objects を使用して、各テーブル、ビュー、インデックス、SP、UDFなどのDDLスクリプトを出力できます。その後、コードで、または WinMerge のような差分ツール。
http://cdttools.com/2011/10/sql-diff-erence/ をご覧ください。これは低コストの代替手段であり、2つのデータベース間でスキーマを調べて、何が変更されたかを示します。その後、SQL Mgmt studioを使用して「スクリプト->変更」を生成し、変更スクリプトを作成できます。 (注意:書きました)
同じデータベースに2つのテーブルがある場合、このクエリを使用できます
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')
BD。のクエリ の一部を変更し、すべてのクレジットは彼に送られます。 (SCHEMA_NAME(schema_id)
がsys.schemas結合に変更されたのは、SCHEMA_NAME(schema_id)
がmaster
である現在のDBコンテキストで動作するため、ソートを変更し、列名を変更し、ステータス列を追加したためです)
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
SQL Management Studioツールを使用して、両方のデータベースから「スクリプトを生成」できます。次に、好みのテキスト比較ツールを使用して、違いを確認します。
昔はこれはうまく機能していましたが、SQL 2005ではスクリプトの生成コードが変更され、オブジェクトが同じ順序で作成されなくなったため、テキスト比較はあまり役に立ちません。 SQLの最新バージョンではこれをテストしていないため、修正されている可能性があります。また、 http://exportsqlscript.codeplex.com/ を試すこともできます。これを使用して、ソースコード管理とバージョン比較のためのスクリプトとしてDDLを出力することに成功しました。
参照: