【问题标题】:Information schema and Primary Keys信息架构和主键
【发布时间】:2011-06-27 19:44:33
【问题描述】:

如何为具有主键的列打印一个“主键”?

如果表有一个主键,我会得到所有列的“主键”,而不是一个具有主键的列,而其他列在 keyType 中为空白。

   SELECT c.TABLE_NAME, 
          c.COLUMN_NAME, 
          c.DATA_TYPE, 
          c.Column_default, 
          c.character_maximum_length, 
          c.numeric_precision, 
          c.is_nullable,
          CASE 
            WHEN u.CONSTRAINT_TYPE = 'PRIMARY KEY' THEN 'primary key'
            ELSE '' 
          END AS KeyType
     FROM INFORMATION_SCHEMA.COLUMNS as c
LEFT JOIN information_schema.table_constraints as u ON c.table_name = u.table_name
 ORDER BY table_name

【问题讨论】:

标签: sql-server sql-server-2005 primary-key constraints information-schema


【解决方案1】:
SELECT  c.TABLE_NAME, c.COLUMN_NAME,c.DATA_TYPE, c.Column_default, c.character_maximum_length, c.numeric_precision, c.is_nullable
             ,CASE WHEN pk.COLUMN_NAME IS NOT NULL THEN 'PRIMARY KEY' ELSE '' END AS KeyType
FROM INFORMATION_SCHEMA.COLUMNS c
LEFT JOIN (
            SELECT ku.TABLE_CATALOG,ku.TABLE_SCHEMA,ku.TABLE_NAME,ku.COLUMN_NAME
            FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc
            INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS ku
                ON tc.CONSTRAINT_TYPE = 'PRIMARY KEY' 
                AND tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME
         )   pk 
ON  c.TABLE_CATALOG = pk.TABLE_CATALOG
            AND c.TABLE_SCHEMA = pk.TABLE_SCHEMA
            AND c.TABLE_NAME = pk.TABLE_NAME
            AND c.COLUMN_NAME = pk.COLUMN_NAME
ORDER BY c.TABLE_SCHEMA,c.TABLE_NAME, c.ORDINAL_POSITION 

【讨论】:

  • 出色的工作,这正是我想要的......我希望我能给你更多的积分。 :o)
  • tc JOIN ku is missing ON ... AND tc.CONSTRAINT_CATALOG = ku.CONSTRAINT_CATALOG AND tc.CONSTRAINT_SCHEMA = ku.CONSTRAINT_SCHEMA
【解决方案2】:

作为补充,请考虑查看:

sp_helptext N'sp_help'

有时向 MS 团队学习是一件很棒的事情。 :-)

【讨论】:

    【解决方案3】:

    第一个答案的一个非常小的补充。可以同时查看 MS_Description(或其他扩展属性)

    SELECT  c.TABLE_NAME, c.COLUMN_NAME,c.DATA_TYPE, c.Column_default,  c.character_maximum_length, c.numeric_precision, c.is_nullable
                 ,CASE WHEN pk.COLUMN_NAME IS NOT NULL THEN 'PRIMARY KEY' ELSE '' END AS KeyType, c.ORDINAL_POSITION 
                 ,convert(varchar(8000), ex.value) as coln
       FROM INFORMATION_SCHEMA.COLUMNS c
       LEFT JOIN (
           SELECT ku.TABLE_CATALOG,ku.TABLE_SCHEMA,ku.TABLE_NAME,ku.COLUMN_NAME
                FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc
                INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS ku
                    ON tc.CONSTRAINT_TYPE = 'PRIMARY KEY' 
                    AND tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME
             )   pk 
        ON  c.TABLE_CATALOG = pk.TABLE_CATALOG
                AND c.TABLE_SCHEMA = pk.TABLE_SCHEMA
                AND c.TABLE_NAME = pk.TABLE_NAME
                AND c.COLUMN_NAME = pk.COLUMN_NAME
        outer apply ::fn_listextendedproperty('MS_Description', 'schema', 'dbo', 'table', c.TABLE_NAME, 'column', c.COLUMN_NAME) ex
       ORDER BY c.TABLE_SCHEMA,c.TABLE_NAME, c.ORDINAL_POSITION 
    

    【讨论】:

      【解决方案4】:

      我发现下面的代码是查找表主键的最简单方法。它只需要 information_schema.columns 表和 information_schema.key_column_usage 表之间的左外连接。

      Select 
        col.column_name, 
        col.data_type, 
        col.ordinal_position, 
        col.is_nullable, 
        case when ky.COLUMN_NAME is null then 0 else 1 end as primary_key_flag
      from <your-catalog>.Information_Schema.columns col
        left outer join <your-catalog>.INFORMATION_SCHEMA.KEY_COLUMN_USAGE ky
          on ky.COLUMN_NAME = col.COLUMN_NAME and ky.TABLE_NAME = col.TABLE_NAME 
            and ky.TABLE_CATALOG = col.TABLE_CATALOG and ky.table_name = col.table_name
      where 
        col.TABLE_NAME = '<your-table-name>' 
        and col.table_catalog = '<your-catalog>';
      

      注意:此代码是使用 SQL Server 2017 Express (14.0.1000) 构建的,在我创建主键后,我能够在 KEY_COLUMN_USAGE 中看到这些值> 表。我还在 CONSTRAINT_TABLE_USAGE 中看到了一条记录,该记录标识了 constraint_name,但我发现这并不是获取显示主键的连接的必要条件.

      最后说明:在离开数据库近十年(使用 MySQL)之后,我才刚刚在个人项目中重新使用 SQL Server,因此我远不是这方面的专家主题。

      【讨论】:

        猜你喜欢
        • 2011-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-03
        • 2010-09-15
        相关资源
        最近更新 更多