[英]How to get PRIMARY KEY COLUMNS of a table (in case of COMPOSITE primary key)
[英]How to get tables and primary key, and display null if the table has no primary key?
我目前正在嘗試通過在C#中調用以下SQL來檢索每個表的表名和主鍵。 這是我到目前為止所嘗試的:
SELECT t.TABLE_NAME As 'Table Name',
Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLES t
left outer join INFORMATION_SCHEMA.TABLE_CONSTRAINTS Constraints
on t.TABLE_NAME = Constraints.Table_name
and t.Table_Schema = Constraints.Table_Schema
left outer join INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys
ON Constraints.TABLE_NAME = Keys.TABLE_NAME
and Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME
and Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'
問題是,如果表沒有主鍵,我希望結果只包含一個“null”條目。 當它工作時,由於某種原因,結果包含“Salary”表的副本,如下所示。 Salary和Employees表都有主鍵,而“Test”表沒有:
編輯:我現在試過這個,它似乎工作。 這樣做有什么不利之處嗎?
SELECT T.TABLE_NAME As 'Table Name'
, (
Select K1.COLUMN_NAME
From INFORMATION_SCHEMA.TABLE_CONSTRAINTS As C1
Join INFORMATION_SCHEMA.KEY_COLUMN_USAGE As K1
On C1.TABLE_SCHEMA = K1.TABLE_SCHEMA
And C1.TABLE_NAME = K1.TABLE_NAME
And C1.CONSTRAINT_NAME = K1.CONSTRAINT_NAME
Where C1.CONSTRAINT_TYPE = 'PRIMARY KEY'
And T.TABLE_SCHEMA = C1.TABLE_SCHEMA
And T.TABLE_NAME = C1.TABLE_NAME
)As PrimaryKeyColumns
FROM INFORMATION_SCHEMA.TABLES As T
嘗試替換此條件Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'
:
SELECT t.TABLE_NAME As 'Table Name',
Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLES t
left outer join INFORMATION_SCHEMA.TABLE_CONSTRAINTS Constraints
on t.TABLE_NAME = Constraints.Table_name
and t.Table_Schema = Constraints.Table_Schema
and Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'
left outer join INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys
ON Constraints.TABLE_NAME = Keys.TABLE_NAME
and Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME
您應該考慮具有多列的PK。 您可以通過更改為子查詢來執行此操作:
SELECT T.TABLE_NAME As 'Table Name'
, Stuff(
(
Select ', ' + K1.COLUMN_NAME
From INFORMATION_SCHEMA.TABLE_CONSTRAINTS As C1
Join INFORMATION_SCHEMA.KEY_COLUMN_USAGE As K1
On C1.TABLE_SCHEMA = K1.TABLE_SCHEMA
And C1.TABLE_NAME = K1.TABLE_NAME
And C1.CONSTRAINT_NAME = K1.CONSTRAINT_NAME
Where C1.CONSTRAINT_TYPE = 'PRIMARY KEY'
And T.TABLE_SCHEMA = C1.TABLE_SCHEMA
And T.TABLE_NAME = C1.TABLE_NAME
For Xml Path(''), type
).value('.', 'nvarchar(max)')
, 1, 2, '') As PrimaryKeyColumns
FROM INFORMATION_SCHEMA.TABLES As T
順便說一句,如果你真的想在頁面視圖中使用連接,你需要嵌套連接。 問題是您有兩個外連接,外鍵中的列在輸出中生成行。 應該注意的是,與前面提到的子查詢方法相比,以下方法的缺點是,如果主鍵由多列組成,您將獲得多行。 也就是說,您可以在SQL Server中嵌套連接,以便它首先處理內部,內部連接,然后處理外部連接:
SELECT T.TABLE_NAME As 'Table Name'
, Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLES As T
Left Join( INFORMATION_SCHEMA.TABLE_CONSTRAINTS Constraints
Join INFORMATION_SCHEMA.KEY_COLUMN_USAGE As Keys
On Constraints.TABLE_SCHEMA = Keys.TABLE_SCHEMA
And Constraints.TABLE_NAME = Keys.TABLE_NAME
And Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME
And Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY' )
On T.TABLE_SCHEMA = Constraints.TABLE_SCHEMA
And T.TABLE_NAME = Constraints.TABLE_NAME
在此查詢中,首先處理TABLE_CONSTRAINTS
和KEY_COLUMN_USAGE
之間的內部連接,並將結果組合在Left Join to TABLES
視圖中。
我看到你已經接受了你的答案,但這是一個純粹的C#答案,以防有人感興趣:
static void Main(string[] args)
{
Server server = new Server("serverName");
Database db = server.Databases["DatabaseName"];
string tableName = "TableName";
Table table = db.Tables[tableName];
if (table != null)
{
Console.WriteLine("Table: {0}", tableName);
if (table.Columns.Count > 0)
{
Console.WriteLine(" Primary Key Columns:");
foreach (Column column in table.Columns)
{
if (column.InPrimaryKey)
{
Console.WriteLine(string.Format(" {0}", column.Name));
}
}
}
else
{
Console.WriteLine(" No primary key.", tableName);
}
}
Console.WriteLine("Press ENTER to exit...");
Console.ReadLine();
}
您將需要添加對Microsoft.SqlServer.Management.Sdk.Sfc和Microsoft.SqlServer.Smo程序集的引用,並導入相應的名稱空間。
select
TABLE_SCHEMA,
TABLE_NAME
from
INFORMATION_SCHEMA.TABLES
where
objectproperty(object_id(table_name),'TableHasPrimaryKey')=0
ORDER BY
TABLE_NAME
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.