获取所有列的列表,其中包含sql server中没有重复列的完整详细信息(Identity,nullable,primary key)

时间:2014-02-13 16:03:11

标签: sql sql-server sql-server-2008

我需要自动化数据库升级过程。 因此,通过获取表的列结构,我需要创建update / insert / create sql语句。

BY问题是我得到重复的列名称,因为约束也出现在我不需要的列表中。那么有没有办法限制结果集中的约束。

我正在使用以下查询

SELECT c.NAME 'Column Name'
,t.NAME 'Data type'
,c.max_length 'Max Length'
,c.precision
,c.scale
,c.is_nullable AS 'Is Nullable'
,c.is_identity AS 'Is Identity'
,ISNULL(i.is_primary_key, 0) 'Primary Key'
,i.type_desc
FROM fblfeb12.sys.columns c
INNER JOIN fblfeb12.sys.types t ON c.system_type_id = t.system_type_id
LEFT OUTER JOIN fblfeb12.sys.index_columns ic ON ic.object_id = c.object_id
AND ic.column_id = c.column_id
LEFT OUTER JOIN fblfeb12.sys.indexes i ON ic.object_id = i.object_id
AND ic.index_id = i.index_id
WHERE c.object_id = OBJECT_ID('table name')

结果集:

 Pms_ID             uniqueidentifier    16  0   0   0   0   CLUSTERED
 Pms_PRODMODELID    uniqueidentifie  16 0   0   1   0NONCLUSTERED
 Pms_PRODMODELID    uniqueidentifier    16  0   0   10NONCLUSTERED
 Pms_PRODMODELID    uniqueidentifier    16  0   0   10NONCLUSTERED
 Pms_ATTRIBUTEID    uniqueidentifier    16  0   0   10NONCLUSTERED
 Pms_ATTRIBUTEID    uniqueidentifier    16  0   0   0NONCLUSTERED
 Pms_ATTRIBUTEID    uniqueidentifier    16  0   0   1NONCLUSTERED

其中PRODMODELIDATTRIBUTEID3次。

我只需要外键列,但在这里我得到索引,我不需要的约束。

我需要column name, data-type,identity,primary key, null able, foreign key

如果我做错了什么,你能为我提供更好的解决方案吗?

3 个答案:

答案 0 :(得分:1)

问题是您要在列上包含所有索引。考虑一下这个简单的表:

CREATE TABLE #T (ID INT NOT NULL CONSTRAINT PK_T_ID PRIMARY KEY);
CREATE INDEX IX_T_ID ON #T (ID);

当您运行自适应查询时:

SELECT c.name, i.name, i.is_primary_key
FROM tempdb.sys.columns c
    LEFT OUTER JOIN tempdb.sys.index_columns ic 
        ON ic.object_id = c.object_id
        AND ic.column_id = c.column_id
    LEFT OUTER JOIN tempdb.sys.indexes i 
        ON ic.object_id = i.object_id
        AND ic.index_id = i.index_id
WHERE c.object_id = OBJECT_ID('tempdb..#T');

对于包含该列(键或非键)的每个索引,将重复列名称,因此结果将为:

name    name    is_primary_key
ID      PK_T_ID     1
ID      IX_T_ID     0

由于您只关心主键,因此您可以将联接中的过滤器应用于sys.indexes以仅返回主键,以便有效地执行此操作,但需要在{{1}之间进行连接}和index_columns INNER JOIN,但保持从indexescolumns的OUTER JOIN,这涉及稍微重新排列连接,所以上面会变成:

index_columns

这将删除重复的结果。最后,您可以查询SELECT c.name, i.name, i.is_primary_key FROM tempdb.sys.columns c LEFT OUTER JOIN (tempdb.sys.index_columns ic INNER JOIN tempdb.sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id AND i.is_primary_key = 1) -- ONLY PRIMARY KEYS ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE c.object_id = OBJECT_ID('tempdb..#T'); 以查明该列是否引用了另一个表,该表提供了最终查询:

sys.foreign_key_columns

N.B我已将列别名从单引号更改为括号,因为不推荐使用单引号(更不用说easily confused with string literals

答案 1 :(得分:0)

如果您使用“DISTINCT”会怎样?所以

SELECT distinct c.NAME...

答案 2 :(得分:0)

“我只需要外键列,但在这里我得到索引,我不需要的约束。”

如果您需要获取外键列,则不能使用此SO post。并删除sys.index_column和sys.indexes?

的连接