原文: MS SQL SERVER搜索某个表的主键所在的列名

SELECT SYSCOLUMNS .name
FROM SYSCOLUMNS , SYSOBJECTS , SYSINDEXES , SYSINDEXKEYS
WHERE SYSCOLUMNS .id = object_id ( 'Tab_XXX' ) --syscolumns.id为该列所属的表对象ID
AND SYSOBJECTS .xtype = 'PK' --sysobjects.xtype对象类型
AND SYSOBJECTS .parent_obj = SYSCOLUMNS .id
AND SYSINDEXES .id = SYSCOLUMNS .id
AND SYSOBJECTS .name = SYSINDEXES .name
AND SYSINDEXKEYS .id = SYSCOLUMNS .id
AND SYSINDEXKEYS .indid = SYSINDEXES .indid --同一表的同一列,可能建有不同类型的索引
AND SYSCOLUMNS .colid = SYSINDEXKEYS .colid

注意:这是在4张系统表中寻找的,关系比较复杂,大致可以表示为:
SYSCOLUMNS 中存有表中的列colid和表id,sysobjects表中存有主键名字(即PK_Table类似)和表id,sysindexes中存 有主键名字和表id和index编号,sysindexkeys中存有表id和index编号和列编号,一项一项对应起来后就能找到列名了。

SELECT * FROM SYSCOLUMNS
--SYSCOLUMNS每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行。
--syscolumns.id为该列所属的表对象ID
--syscolumns.colid为该列对象ID

SELECT * FROM SYSOBJECTS
--SYSOBJECTS在数据库内创建的每个对象(约束、默认值、日志、规则、存储过程、表、视图、等)在表中占一行。
--sysobjects.xtype对象类型
--sysobjects.parent_obj父对象的对象标识号(例如,对于触发器或约束,该标识号为表id)
--sysobjects.name对象名称,这里为主键名字(即PK_Table类似)


SELECT * FROM SYSINDEXES
--数据库中的每个索引和表在表中各占一行。
--sysindexes.id 表ID(如果 indid = 0 或 255)。否则为索引所属表id。
--sysindexes.name 表名(如果 indid = 0 或 255)。否则为索引的名称。这里为有主键名字(主键必为索引,见下述分析)
--sysindexes.indid 索引ID的类型

SELECT * FROM SYSINDEXKEYS
--数据库中的每个索引和表在表中各占一行。
--sysindexkeys.id      表ID
--sysindexkeys.indid  索引ID的类型
--sysindexkeys.colid   列ID

主键一定是唯一性索引,唯一性索引并不一定就是主键

所谓主键就是能够唯一标识表中某一行的属性或属性组,一个表只能有一个主键,但可以有多个候选索引。因为主键可以唯一标识某一行记录,所以可以确保执行数据更新、删除的时候不会出现张冠李戴的错误。主键除了上述作用外,常常与外键构成参照完整性约束,防止出现数据不一致。数据库在设计时,主键起到了很重要的作用。

主键可以保证记录的唯一和主键域非空, 数据库管理系统对于主键自动生成唯一索引,所以主键也是一个特殊的索引。

【SQL开发实战技巧】系列(八):聊聊如何插入数据时比约束更灵活的限制数据插入以及怎么一个insert语句同时插入多张表
插入数据、阻止对某几列插入的实现、复制表的定义和数据以及注意事项、比创建约束功能更强大!用 WITH CHECK OPTION限制数据录入、如何一个insert将数据同时插入多个表【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。但是!ORA - 01723 : 不允许长度为 0 的列。
使用PD(PowerDesigner)图如何快速生成创建数据库表的SQL脚本并生成表在数据库
使用PD(PowerDesigner)图如何快速生成创建数据库表的SQL脚本并生成表在数据库