[英]SQL Server: compare columns in two tables
我最近完成了從某個應用程序的舊版本遷移到當前版本的遷移,並且在遷移數據庫時遇到了一些問題。
我需要一個查詢來幫助我比較兩個表中的列。 我的意思不是行中的數據,我需要比較列本身以找出我錯過了表結構的哪些變化。
否則這里是一個開始(對於 sql server)
select
so.name as [table],
sc.name as [column],
sc.type, sc.length, sc.prec, sc.scale, sc.collation
from
sysobjects so
inner join syscolumns sc ON so.id = sc.id
where so.type='u'
order by so.name, sc.colorder
你可以看看
- INFORMATION_SCHEMA.TABLES
- INFORMATION_SCHEMA.COLUMNS
- INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
- INFORMATION_SCHEMA.TABLE_CONSTRAINTS
- INFORMATION_SCHEMA.KEY_COLUMN_USAGE
如果你想更深入,表格..
[更新]
使用 INFORMATION_SCHEMA 表
SELECT
[table].TABLE_NAME AS [Table_Name],
[column].COLUMN_NAME AS [Column_Name],
COLUMNPROPERTY(object_id([table].[TABLE_NAME]), [column].[COLUMN_NAME], 'IsIdentity') AS [identity],
[column].DATA_TYPE AS [datatype],
[column].CHARACTER_MAXIMUM_LENGTH AS [Character_Length],
[column].NUMERIC_PRECISION AS Numeric_precision,
[column].ORDINAL_POSITION AS [order],
[column].COLUMN_DEFAULT AS [defaultvalue],
[column].IS_NULLABLE AS [nullable]
FROM
INFORMATION_SCHEMA.TABLES [table] INNER JOIN
INFORMATION_SCHEMA.COLUMNS [column] ON [table].TABLE_NAME = [column].TABLE_NAME
WHERE
[table].TABLE_TYPE = 'BASE TABLE'
AND [table].TABLE_NAME <> 'sysdiagrams'
ORDER BY
[table].TABLE_NAME ASC,
[column].ORDINAL_POSITION ASC
我真的建議您使用第三方比較工具,例如上面已經提到的 SQL Compare 或ApexSQL Diff或基本上市場上的任何其他工具。
即使這些是商業工具,如果您真的不需要每天都這樣做,您也可以獲得免費試用並完成工作。
如果您真的需要為此使用 SQL,您可以嘗試像這樣非常簡單的查詢,然后在此基礎上進行構建。
select T.name, C.*
from sys.tables T
inner join sys.columns C on T.object_id = C.object_id
where T.name = 'table_name'
這對我有用(有同樣的問題,只是編譯了我的解決方案)
DECLARE @TableOne VARCHAR(2048) = '',
@TableTwo VARCHAR(2048) = ''
-- In TableOne but not in TableTwo
SELECT DISTINCT
@TableOne AS [First table],
'>>' AS Dir, --Direction
@TableTwo AS [Second table],
a.COLUMN_NAME,
a.DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS a
WHERE a.COLUMN_NAME NOT IN (SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS b
WHERE b.TABLE_NAME = @TableTwo)
AND a.TABLE_NAME = @TableOne
UNION ALL
-- In TableTwo but not in TableOne
SELECT DISTINCT
@TableOne AS [First table],
'<<' AS Dir, --Direction
@TableTwo AS [Second table],
a.COLUMN_NAME,
a.DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS a
WHERE a.COLUMN_NAME NOT IN (SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS b
WHERE b.TABLE_NAME = @TableOne)
AND a.TABLE_NAME = @TableTwo
ORDER BY Dir DESC, COLUMN_NAME ASC
只需為@TableOne 和@TableTwo 設置值並運行腳本;)
真的,這是一個大劇本。 :)
使用紅門 sql 比較。 他們為您提供 14 天免費試用
如果你真的需要腳本,它可以是一個文本,然后你可以使用任何文本比較器來比較兩者。
我發現 Qcpbraca 的解決方案最符合我的要求,但至少對我而言,感覺在視覺上查看結果並知道缺少哪一列有點困難。 我也經常有列名匹配但數據類型不匹配,所以我也將它添加到下面的代碼中。
以下腳本擴展了 Qcpbraca 的腳本,因此如果您發現這對投票有幫助,請考慮對 Qcpbraca 的回答進行投票。
DECLARE @Table1 VARCHAR(2048) = 'Table_1',
@Table2 VARCHAR(2048) = 'Table_2'
-- Table 1 Columns into #temp_table_1
SELECT DISTINCT
a.COLUMN_NAME AS [Column Name],
a.DATA_TYPE as [Data Type],
a.CHARACTER_MAXIMUM_LENGTH,
a.NUMERIC_PRECISION,
a.NUMERIC_SCALE
into #temp_table1
FROM INFORMATION_SCHEMA.COLUMNS a
where a.TABLE_NAME = @Table1
order by a.COLUMN_NAME
-- Table 2 Columns into #temp_table_2
SELECT DISTINCT
a.COLUMN_NAME AS [Column Name],
a.DATA_TYPE as [Data Type],
a.CHARACTER_MAXIMUM_LENGTH,
a.NUMERIC_PRECISION,
a.NUMERIC_SCALE
into #temp_table2
FROM INFORMATION_SCHEMA.COLUMNS a
where a.TABLE_NAME = @Table2
order by a.COLUMN_NAME
select
@Table1 [Table 1],
isnull(t1.[Column Name],'') [Table 1 Column Name],
isnull(t2.[Column Name],'') [Table 2 Column Name],
@Table2 [Table 2],
isnull(t1.[Data Type],'') [Table 1 Column Type],
isnull(t2.[Data Type],'') [Table 2 Column Type],
isnull(cast(t1.CHARACTER_MAXIMUM_LENGTH as varchar(50)),isnull(cast(t1.NUMERIC_PRECISION as varchar(50)),'') + ',' +
isnull(cast(t1.NUMERIC_SCALE as varchar(50)),'')) [Table 1 Column Precision],
isnull(cast(t2.CHARACTER_MAXIMUM_LENGTH as varchar(50)),isnull(cast(t2.NUMERIC_PRECISION as varchar(50)),'') + ',' +
isnull(cast(t2.NUMERIC_SCALE as varchar(50)),'')) [Table 2 Column Precision],
--[Data Type Warning]
case when isnull(t1.[Column Name],'') = isnull(t2.[Column Name],'')
and (
isnull(t1.[Data Type],'') <> isnull(t2.[Data Type],'')
or
isnull(cast(t1.CHARACTER_MAXIMUM_LENGTH as varchar(50)),isnull(cast(t1.NUMERIC_PRECISION as varchar(50)),'') + ',' +
isnull(cast(t1.NUMERIC_SCALE as varchar(50)),''))
<>
isnull(cast(t2.CHARACTER_MAXIMUM_LENGTH as varchar(50)),isnull(cast(t2.NUMERIC_PRECISION as varchar(50)),'') + ',' +
isnull(cast(t2.NUMERIC_SCALE as varchar(50)),''))
)
then '*** Data Type Mismatch ***' else '' end
[Data Type Warning]
from #temp_table1 t1
full outer join #temp_table2 t2 on t1.[Column Name] = t2.[Column Name]
where 1=1
drop table #temp_table1, #temp_table2
go
這是一個示例結果集:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.