sqlserver查询表结构
很多人查表结构,询表第一反应是结构打开 SSMS,右键表,询表设计。结构这法子直观,询表但只能看一个表。结构要是询表让你对比三个库里的同一张表,或者把结构导出来给同事,结构鼠标点到手酸也搞不完。询表真正干活的结构时候,SQL 才是询表最快的。
最常用的结构系统视图就两个:INFORMATION_SCHEMA.COLUMNS 和 sys.columns。前者是询表 SQL 标准,跨库通用;后者是结构 SQL Server 亲儿子,信息更全。询表我平时用 sys.columns 多些,因为能直接关联到 sys.types,拿到准确的数据类型,不会出现 nvarchar 被截成 varchar 这种尴尬。
先看个最简单的。查 Orders 表有哪些列:
SELECT c.name AS column_name, t.name AS data_type, c.max_length, c.is_nullable FROM sys.columns c JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE c.object_id = OBJECT_ID('dbo.Orders') ORDER BY c.column_id; OBJECT_ID 这个函数很关键。它把表名转成内部 ID,不用你去猜 object_id 是多少。注意要带 schema 名,dbo.Orders,不然它按默认 schema 找,有时候会扑空。
max_length 有个坑。对 nvarchar(50),它返回 100,因为字节数。想看字符数得除以 2,或者干脆用 INFORMATION_SCHEMA.COLUMNS 里的 CHARACTER_MAXIMUM_LENGTH,那个直接就是 50。所以看字符长度,我切到 INFORMATION_SCHEMA;看物理存储,我用 sys.columns。
主键、外键这些约束,得查 sys.key_constraints 和 sys.foreign_keys。比如找 Orders 的主键列:
SELECT col.name FROM sys.key_constraints kc JOIN sys.index_columns ic ON kc.parent_object_id = ic.object_id AND kc.unique_index_id = ic.index_id JOIN sys.columns col ON ic.object_id = col.object_id AND ic.column_id = col.column_id WHERE kc.parent_object_id = OBJECT_ID('dbo.Orders') AND kc.type = 'PK'; 这段有点绕,但跑一次就明白。关键在 unique_index_id 和 index_id 的关联,主键本质是个唯一索引,所以绕到 sys.index_columns 里找列。
默认值在 sys.default_constraints 里。查 Orders 表 Status 列的默认值:
SELECT d.definition FROM sys.default_constraints d JOIN sys.columns c ON d.parent_object_id = c.object_id AND d.parent_column_id = c.column_id WHERE d.parent_object_id = OBJECT_ID('dbo.Orders') AND c.name = 'Status'; definition 字段返回的是带括号的表达式,比如 ((0))。别觉得奇怪,SQL Server 存的就是这个格式。
想一次性把表结构导成文本,用 INFORMATION_SCHEMA.COLUMNS 拼字符串更省事:
SELECT COLUMN_NAME + ' ' + DATA_TYPE + ISNULL('(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')', '') + CASE WHEN IS_NULLABLE = 'NO' THEN ' NOT NULL' ELSE '' END FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Orders' ORDER BY ORDINAL_POSITION; 这脚本我改过好几版。最早没处理 NULL 的字符长度,结果 int 类型后面跟个空括号,难看。后来加了 ISNULL 才顺眼。
有个细节:sys.columns 里 is_identity、is_computed 这些布尔字段,比 INFORMATION_SCHEMA 全。要查自增列,直接 WHERE is_identity = 1,干净利落。INFORMATION_SCHEMA 得绕到 COLUMNPROPERTY 去,麻烦。
临时表的结构也能查,不过得用 tempdb.sys.columns,加 tempdb.. 前缀。有次排查一个存储过程,里面建了堆临时表,我就是这么把结构扒出来的。
最后说个习惯。我本地有个 sp_help 的替代脚本,叫 usp_GetTableStructure,参数就表名。跑一下,列名、类型、长度、是否可空、默认值、主键标记全出来,直接复制到 Excel 就能发给前端。比 SSMS 里右键再点“编写表脚本”快得多,尤其是表多的时候。
查表结构这事,工具顺手了,排查问题、写文档、对接口,都省时间。别老依赖图形界面,敲几行 SQL,心里更有底。