【问题标题】:How can I select the primary key columns from a table?如何从表中选择主键列?
【发布时间】:2011-03-01 10:15:56
【问题描述】:

我需要选择作为主键的列或不为空的列。我该怎么做?

我只想要列,而不是值。

【问题讨论】:

  • 你只想要列而不想要值是什么意思?
  • 您使用的是哪个数据库?
  • 你能显示你需要从中选择主键列的表和示例值吗?

标签: sql sql-server-2008


【解决方案1】:

要列出主键列,您可以尝试以下查询:

SELECT
    kc.name,
    c.NAME
FROM 
    sys.key_constraints kc
INNER JOIN 
    sys.index_columns ic ON kc.parent_object_id = ic.object_id  and kc.unique_index_id = ic.index_id
INNER JOIN 
    sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE
    kc.type = 'PK'

要列出外键,请使用以下命令:

SELECT
    OBJECT_NAME(parent_object_id) 'Parent table',
    c.NAME 'Parent column name',
    OBJECT_NAME(referenced_object_id) 'Referenced table',
    cref.NAME 'Referenced column name'
FROM 
    sys.foreign_key_columns fkc
INNER JOIN 
    sys.columns c 
       ON fkc.parent_column_id = c.column_id 
          AND fkc.parent_object_id = c.object_id
INNER JOIN 
    sys.columns cref 
       ON fkc.referenced_column_id = cref.column_id 
          AND fkc.referenced_object_id = cref.object_id

希望这会有所帮助。

【讨论】:

  • 我不确定主键查询是否正确 - 它在我的测试数据库中返回额外的非主键字段。
  • @Peter kelly 这个查询检索所有有或没有约束的列。
  • 外键查询非常出色,但正如 PeterKelly 和 Craig 所指出的,主键查询列出了表上的所有其他索引——除了主键约束.
  • 建议的编辑应该解决显示所有键的问题。现在应该只显示 PKs
【解决方案2】:

列出主键列

为了列出主键列,我使用了 SQL Server 的 ANSI 标准 Information Schema Views 的实现,因为它们更易于使用:无需使用 object_name() 函数将 object_ids 转换为人工 -可读的名字。

我使用[INFORMATION_SCHEMA].[KEY_COLUMN_USAGE] 列出 对表的约束——主键和外键; [INFORMATION_SCHEMA].CONSTRAINT_COLUMN_USAGE 有类似的信息,但 缺少ORDINAL_POSITION

[INFORMATION_SCHEMA].[TABLE_CONSTRAINTS] 提供有关 约束(最重要的是CONSTRAINT_TYPE),但没有列出约束适用的列。

要获取主键使用的唯一列列表,请加入上述 使用约束名称的两个表:

SELECT
     tc.TABLE_SCHEMA
    ,tc.TABLE_NAME
    ,tc.CONSTRAINT_NAME
    ,kcu.COLUMN_NAME
    ,kcu.ORDINAL_POSITION
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc

INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu
    ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME

WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND tc.TABLE_NAME = @TableName

【讨论】:

  • 不错的观察。我没有注意到它。谢谢
【解决方案3】:

下一个答案更合适,我不确定如何转移接受的答案。

SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS  
WHERE TABLE_NAME = '<TABLE_NAME>' and IS_NULLABLE = 'NO'

【讨论】:

  • 非空列不一定是主键
  • Primary Keys 不能为 NULL,但问题询问是否为 PK。
【解决方案4】:

您可以使用名为 INFORMATION_KEY_COLUMN_USAGE 的内置系统视图来获取主键列

SELECT [COLUMN_NAME]
FROM [DatabaseName].[INFORMATION_SCHEMA].[KEY_COLUMN_USAGE]
WHERE [TABLE_NAME] = 'TableName'

【讨论】:

  • 它再次带回了 FK 和 IX 列。
【解决方案5】:
SELECT * FROM INFORMATION_SCHEMA.COLUMNS  
WHERE TABLE_NAME = '<your_table>' and COLUMN_KEY = 'PRI'

这个例子是在 mariadb、mysql 上测试的。 可能适用于其他人,但取决于 information_schema 详细信息。

【讨论】:

    【解决方案6】:

    仅使用 sys.* 表:

    select
        t.name,
        kc.type,
        kc.name,
        c.name,
        i.is_unique,
        i.is_primary_key,
        i.is_unique_constraint,
        ic.is_descending_key,
        ic.key_ordinal,
        ic.is_included_column
    from sys.key_constraints kc
    inner join sys.objects t on t.object_id = kc.parent_object_id
    inner join sys.indexes i on i.name = kc.name
    inner join sys.index_columns ic on ic.object_id = kc.parent_object_id and ic.index_id = i.index_id
    inner join sys.columns c on c.object_id = kc.parent_object_id and c.column_id = ic.column_id
    order by
        t.name,
        kc.type,
        kc.name,
        ic.key_ordinal
    

    【讨论】:

      【解决方案7】:

      毕竟我自己找到了解决方案:

      select sc.name from sys.objects as so
      inner join sys.indexes as si        on so.object_id = si.object_id 
                                          and si.is_primary_key = 1
      inner join sys.index_columns as ic  on si.object_id = ic.object_id
                                          and si.index_id = ic.index_id
      inner join sys.columns as sc            on so.object_id = sc.object_id
                                          and ic.column_id = sc.column_id
      where so.object_id = object_id('TABLE_NAME')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多