2017-06-20 100 views
0

我需要從選定數據庫中的每個表中獲取主鍵(如果存在),標識(如果存在)以及名爲「ID」(如果存在)的列。我得到了SQL查詢來完成這項工作,但查詢返回記錄,其中主鍵有時同時包含「否」和「是」值。因此,產生多行數據,所以我使用了DISTINCT這個詞來刪除重複數據。我假設這是由於某些列上定義的索引。從數據庫表中檢索主鍵,標識列和特定名稱列

如何解決這個問題?使用

SQL查詢:

SELECT DISTINCT 
    object_name(i.object_id) [Table], 
    c.name [Column], 
    IIF(i.is_primary_key = 1, 'Yes', 'No') [PK], 
    IIF(c.is_identity = 1, 'Yes', 'No') [Identity], 
    IIF(UPPER(c.name) = 'ID', 'Yes', 'No') [Named ID] 
FROM sys.indexes i 
    INNER JOIN sys.columns c ON c.object_id = i.object_id 
    INNER JOIN sys.identity_columns idc ON idc.object_id = c.object_id AND idc.column_id = c.column_id 
WHERE 
    i.is_primary_key = 1 OR c.is_identity = 1 OR c.name = 'ID' 
ORDER BY [Table]; 
+0

我不明白這裏查詢。您是否嘗試使用主鍵,身份或命名ID的所有列?你想爲複合鍵發生什麼? –

+0

我需要檢查可能用作唯一標識符的列的所有表。列上的主鍵意味着將使用PK。如果未找到PK,將使用Identity(自動增量)行。最後,如果沒有PK或自動增量(標識)列,那麼將使用名爲「ID」的列。所以PK> Identity>「ID」命名列。因此,我需要列出有關每個表格的信息。 –

+0

列總是被命名。 –

回答

0

對於任何人都需要在今後發生類似的事情,我採用了彼得的答案的版本(包括肖恩·蘭格建議使用SYS.TABLES):

SELECT 
    t.name AS [Table], 
    c.name AS [Column], 
    CASE i.is_primary_key WHEN 1 THEN 'Yes' ELSE 'No' END [PK], 
    CASE idc.is_identity WHEN 1 THEN 'Yes' ELSE 'No' END [Identity], 
    CASE c.name WHEN 'ID' THEN 'Yes' ELSE 'No' END [Named ID] 
FROM 
    sys.tables t 
    LEFT JOIN sys.columns c ON c.object_id = t.object_id 
    LEFT JOIN sys.identity_columns idc ON idc.object_id = t.object_id AND idc.column_id = c.column_id AND idc.is_identity = 1 
    LEFT JOIN sys.index_columns ic ON ic.object_id = t.object_id AND ic.column_id = c.column_id 
    LEFT JOIN sys.indexes i ON i.object_id = t.object_id AND i.index_id = ic.index_id AND i.is_primary_key = 1 
WHERE t.type = 'U' AND (idc.is_identity = 1 OR i.is_primary_key = 1 OR c.name = 'ID') 
ORDER BY t.name, c.name; 
+0

如果您需要架構信息並且不介意在查詢中添加額外的複雜性,您還可以查看Hector Diaz的解決方案。 –

0

您正在使用SYS.INDEXES。一個表可以有多個索引,一個列可以使用多個索引。你的查詢告訴你的是該列在PK索引中以及在另一個索引(這不是PK索引)中使用。

此外,您的查詢將排除不在索引中的所有列。

從sys.columns開始,改爲使用外部連接。對象標識是表的標識,而不是列的標識,因此您還需要index_columns。

SELECT DISTINCT 
    object_name(c.object_id) [Table], 
    c.name [Column], 
    i.is_primary_key, 
    case i.is_primary_key when 1 then 'Yes' else 'No'end [PK], 
    case c.is_identity when 1 then 'Yes' else 'No'end [Identity], 
    case c.name when 'ID' then 'Yes' else 'No'end [Named ID] 
FROM sys.columns c 
    left join sys.index_columns ic on c.column_id = ic.column_id and c.object_id = ic.object_id 
    left JOIN sys.indexes i ON i.index_id = ic.index_id and c.object_id = i.object_id and i.is_primary_key= 1 
    left JOIN sys.identity_columns idc ON idc.object_id = c.object_id AND idc.column_id = c.column_id 
WHERE i.is_primary_key = 1 OR c.is_identity = 1 OR c.name = 'ID' 
ORDER BY [Table]; 
+0

嗨,彼得,我意識到索引是問題。但是,我將如何解決這個問題。是否可以過濾索引? –

+0

你能建議如何解決這個問題,或建議一個更好的方法來獲得我需要的信息?謝謝。 –

+0

@SamirSuljkanovic我已經更新了我的答案,包括一個查詢。 – Peter

0

你可以做下面的查詢,但是你可以得到結果,其中多列形成類似如下主鍵:

Multiple columns form the primary key

的,因爲像

ALTER TABLE [derived].[LocationParameterMedium] 
ADD CONSTRAINT [PK_LocationParameterMedium] PRIMARY KEY CLUSTERED ([CycleID] ASC, [LocationID] ASC, [ParameterID] ASC, [MediumID] ASC) 
GO 

可以通過列捲起成一列固定的following link explains how to roll-up columns into a single column

查詢:

SELECT 
    OBJECT_SCHEMA_NAME(t.object_id) AS [Schema], -- Incase there is mulple schemas and same table name 
    t.name AS [Table], 
    c.name AS [Column], 
    IIF((SELECT 1 
     FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE keyCU 
     WHERE keyCU.COLUMN_NAME = c.name 
      AND keyCU.TABLE_SCHEMA = OBJECT_SCHEMA_NAME(t.object_id) 
      AND keyCU.TABLE_NAME = t.name 
      AND OBJECTPROPERTY(OBJECT_ID(keyCU.CONSTRAINT_SCHEMA + '.' + QUOTENAME(keyCU.CONSTRAINT_NAME)), 'IsPrimaryKey') = 1) = 1, 'Yes', 'No') [PK], 
    IIF(c.is_identity = 1, 'Yes', 'No') [Identity], 
    IIF(c.name = 'ID', 'Yes', 'No') [Named ID] 
FROM sys.tables AS t 
LEFT JOIN sys.columns AS c 
    ON t.object_id = c.object_id 
    AND (c.is_identity = 1 
     OR c.name = 'ID' 
     OR EXISTS (SELECT 1 
        FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE keyCU 
        WHERE keyCU.COLUMN_NAME = c.name 
         AND keyCU.TABLE_SCHEMA = OBJECT_SCHEMA_NAME(t.object_id) 
         AND keyCU.TABLE_NAME = t.name 
         AND OBJECTPROPERTY(OBJECT_ID(keyCU.CONSTRAINT_SCHEMA + '.' + QUOTENAME(keyCU.CONSTRAINT_NAME)), 'IsPrimaryKey') = 1 
       ) 
    ) 
---- To exclude tables where there is no PK, identity, or column name = 'ID' 
--WHERE c.name IS NOT NULL