应使用 sys.columns 而非 INFORMATION_SCHEMA.COLUMNS 查表结构,因其字段全、可靠性高,包含 is_nullable、max_length、precision 等关键属性,并支持通过联查 sys.types、sys.tables 获取准确类型名和列顺序。

查表结构用 sys.columns 而不是 INFORMATION_SCHEMA.COLUMNS
SQL Server 里最可靠、字段最全的列定义来源是系统视图 sys.columns,它包含 is_nullable、max_length、precision、scale、user_type_id 等关键信息。而 INFORMATION_SCHEMA.COLUMNS 是跨数据库兼容视图,会丢失 SQL Server 特有属性(比如计算列、稀疏列、标识列状态),且不暴露 column_id 顺序或 is_computed 标志。
实操建议:
- 优先联查
sys.columns+sys.types+sys.tables,通过user_type_id关联获取真实数据类型名(如varchar而非sysname) - 用
column_id排序,确保列顺序与 SSMS 中一致 - 过滤时用
object_id而非表名字符串比较,避免同名不同 Schema 的歧义
快速获取某张表的完整列定义(含类型、长度、是否为空)
下面这个查询能直接输出可读性强的列清单,覆盖常见需求:
SELECT
c.name AS column_name,
t.name AS data_type,
c.max_length,
c.precision,
c.scale,
c.is_nullable,
c.is_identity,
c.is_computed
FROM sys.columns c
JOIN sys.types t ON c.user_type_id = t.user_type_id
WHERE c.object_id = OBJECT_ID('dbo.YourTableName');
注意点:
-
max_length对varchar/char是字节数,对nvarchar/nchar是字节数 ×2;对int这类固定长度类型恒为 4 -
precision和scale仅对数值类型有效,其他类型为 0 或 NULL - 如果表在非
dboSchema 下,必须把'dbo.YourTableName'改成完整三段式名,例如'sales.Customers'
区分用户表和系统表,避免误查 sys 视图本身
直接查 sys.columns 会返回所有对象(包括系统表、视图、函数等)的列,容易混入无关结果。实际查业务表时,必须加筛选条件。
正确做法:
- 联查
sys.tables并限制t.type = 'U'(用户表),排除视图('V')、系统表('S') - 或者用
OBJECTPROPERTY(c.object_id, 'IsUserTable') = 1做二次校验 - 不要依赖
sys.objects.name模糊匹配(比如LIKE 'sys%'),因为用户也可能建以sys开头的表名
想查主键、外键、索引列?得换系统视图
sys.columns 只管“列存在”,不管“列被怎么用”。主键列需要查 sys.indexes + sys.index_columns,外键要查 sys.foreign_keys + sys.foreign_key_columns。这些关系信息不会出现在列元数据里。
例如查主键列:
SELECT c.name
FROM sys.indexes i
JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE i.object_id = OBJECT_ID('dbo.YourTableName')
AND i.is_primary_key = 1;
这里容易漏掉的是:一个主键可能是联合主键(多列),所以不能只查单列;另外,sys.index_columns.key_ordinal 决定列在主键里的顺序,但很多脚本会忽略它,导致导出 DDL 时顺序错乱。

















