我最近完成了从某个应用程序的旧版本到当前版本的迁移,我在迁移数据库时遇到了一些问题。
我需要一个可以帮助我比较两个表中的列的查询。我的意思不是行中的数据,我需要比较列本身来弄清楚,我错过了表结构的哪些变化。
答案 0 :(得分:12)
否则这是一个开始(对于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
答案 1 :(得分:8)
我真的建议您使用第三方比较工具,例如上面已经提到的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'
答案 2 :(得分:6)
真的,这是一个很大的脚本。 :)
使用红门sql比较。他们为您提供14天免费试用
如果你真的需要脚本,它可以是一个文本,而不是你可以使用任何文本比较器进行比较。
答案 3 :(得分:5)
这适合我(有同样的问题,只是编译了我的解决方案)
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设置值并运行脚本;)
答案 4 :(得分:0)
我发现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
这是示例结果集: