2017-05-10 115 views
3

我使用以下SQL来查询给定表的键(主键和外键)及其描述。我正在使用SQL Server 2005.列出一张表的所有外键,同一表的多个外键

SELECT c.name 'Column Name' , 
    t.name 'Data type' , 
    c.max_length 'Max Length' , 
    c.precision , 
    c.scale , 
    c.is_nullable , 
    ISNULL(i.is_primary_key, 0) 'Primary Key' , 
    CAST ((SELECT COUNT(*) 
      FROM (SELECT cx.object_id 
         FROM  sys.foreign_key_columns fkc 
           INNER JOIN sys.columns cx ON fkc.parent_column_id = cx.column_id 
                  AND fkc.parent_object_id = cx.object_id 
           INNER JOIN sys.columns cref ON fkc.referenced_column_id = cref.column_id 
                  AND fkc.referenced_object_id = cref.object_id 
         WHERE  cx.column_id = c.column_id 
           AND fkc.parent_object_id = OBJECT_ID('[dbo].Cards') 
        ) xxx 
     ) AS BIT) AS 'Foreign Key' , 
    (SELECT OBJECT_SCHEMA_NAME(fkc.referenced_object_id) 
     FROM  sys.foreign_key_columns fkc 
       INNER JOIN sys.columns cy ON fkc.parent_column_id = cy.column_id 
              AND fkc.parent_object_id = cy.object_id 
       INNER JOIN sys.columns cref ON fkc.referenced_column_id = cref.column_id 
               AND fkc.referenced_object_id = cref.object_id 
     WHERE  cy.column_id = c.column_id 
       AND fkc.parent_object_id = OBJECT_ID('[dbo].Cards') 
    ) 'Schema Name' , 
    (SELECT OBJECT_NAME(referenced_object_id) 
     FROM  sys.foreign_key_columns fkc 
       INNER JOIN sys.columns cy ON fkc.parent_column_id = cy.column_id 
              AND fkc.parent_object_id = cy.object_id 
       INNER JOIN sys.columns cref ON fkc.referenced_column_id = cref.column_id 
               AND fkc.referenced_object_id = cref.object_id 
     WHERE  cy.column_id = c.column_id 
       AND fkc.parent_object_id = OBJECT_ID('[dbo].Cards') 
    ) 'Referenced table' , 
    (SELECT cref.name 
     FROM  sys.foreign_key_columns fkc 
       INNER JOIN sys.columns cy ON fkc.parent_column_id = cy.column_id 
              AND fkc.parent_object_id = cy.object_id 
       INNER JOIN sys.columns cref ON fkc.referenced_column_id = cref.column_id 
               AND fkc.referenced_object_id = cref.object_id 
     WHERE  cy.column_id = c.column_id 
       AND fkc.parent_object_id = OBJECT_ID('[dbo].Cards') 
    ) 'Referenced column name' , 
    (SELECT sep.value [Description] 
     FROM  sys.extended_properties sep 
     WHERE  OBJECT_ID('[dbo].Cards') = sep.major_id 
       AND c.column_id = sep.minor_id 
    ) Description FROM sys.columns c 
    INNER JOIN sys.types t ON c.user_type_id = t.user_type_id 
    LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id 
              AND ic.column_id = c.column_id 
    LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id 
            AND ic.index_id = i.index_id WHERE c.object_id = OBJECT_ID('[dbo].Cards'); 

查询对所有表都非常适用,除非表中有两个外键指向同一个表。

我得到的错误是,

"Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression." 

我在做什么错?

回答

1

我没有检查你的第二个查询,但问题仍然存在: 是returnes超过1个值子查询是这样的一个

(SELECT sep.value [Description] 
    FROM  sys.extended_properties sep 
    WHERE  OBJECT_ID('person.stateProvince') = sep.major_id 
      AND c.column_id = sep.minor_id     
) Description 

你应该在where子句中添加附加条件:

and class = 1 -- OBJECT_OR_COLUMN 

您的查询不考虑表超过1个指数,加盟上c.column_id = sep.minor_id你的猫得到更多的行,因为上课的时候我s 7(index)minor_id是索引id,而不是列id

+0

谢谢你的回答!问题通过在查询的三个部分添加TOP 1来解决。为我工作足够:) – Excessive

0

我已经解决了我自己的问题。

张贴在这里,以防有人绊倒这个问题。

SELECT c.name 'Column Name' , 
    t.name 'Data type' , 
    c.max_length 'Max Length' , 
    c.precision , 
    c.scale , 
    c.is_nullable , 
    ISNULL(i.is_primary_key, 0) 'Primary Key' , 
    CAST ((SELECT COUNT(*) 
      FROM (SELECT cx.object_id 
         FROM  sys.foreign_key_columns fkc 
           INNER JOIN sys.columns cx ON fkc.parent_column_id = cx.column_id 
                  AND fkc.parent_object_id = cx.object_id 
           INNER JOIN sys.columns cref ON fkc.referenced_column_id = cref.column_id 
                  AND fkc.referenced_object_id = cref.object_id 
         WHERE  cx.column_id = c.column_id 
           AND fkc.parent_object_id = OBJECT_ID('[dbo].Cards') 
        ) xxx 
     ) AS BIT) AS 'Foreign Key' , 
    (SELECT TOP 1 OBJECT_SCHEMA_NAME(fkc.referenced_object_id) 
     FROM  sys.foreign_key_columns fkc 
       INNER JOIN sys.columns cy ON fkc.parent_column_id = cy.column_id 
              AND fkc.parent_object_id = cy.object_id 
       INNER JOIN sys.columns cref ON fkc.referenced_column_id = cref.column_id 
               AND fkc.referenced_object_id = cref.object_id 
     WHERE  cy.column_id = c.column_id 
       AND fkc.parent_object_id = OBJECT_ID('[dbo].Cards') 
    ) 'Schema Name' , 
    (SELECT TOP 1 OBJECT_NAME(referenced_object_id) 
     FROM  sys.foreign_key_columns fkc 
       INNER JOIN sys.columns cy ON fkc.parent_column_id = cy.column_id 
              AND fkc.parent_object_id = cy.object_id 
       INNER JOIN sys.columns cref ON fkc.referenced_column_id = cref.column_id 
               AND fkc.referenced_object_id = cref.object_id 
     WHERE  cy.column_id = c.column_id 
       AND fkc.parent_object_id = OBJECT_ID('[dbo].Cards') 
    ) 'Referenced table' , 
    (SELECT TOP 1 cref.name 
     FROM  sys.foreign_key_columns fkc 
       INNER JOIN sys.columns cy ON fkc.parent_column_id = cy.column_id 
              AND fkc.parent_object_id = cy.object_id 
       INNER JOIN sys.columns cref ON fkc.referenced_column_id = cref.column_id 
               AND fkc.referenced_object_id = cref.object_id 
     WHERE  cy.column_id = c.column_id 
       AND fkc.parent_object_id = OBJECT_ID('[dbo].Cards') 
    ) 'Referenced column name' , 
    (SELECT sep.value [Description] 
     FROM  sys.extended_properties sep 
     WHERE  OBJECT_ID('[dbo].Cards') = sep.major_id 
       AND c.column_id = sep.minor_id 
    ) Description FROM sys.columns c 
    INNER JOIN sys.types t ON c.user_type_id = t.user_type_id 
    LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id 
              AND ic.column_id = c.column_id 
    LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id 
            AND ic.index_id = i.index_id WHERE c.object_id = OBJECT_ID('[dbo].Cards');