C# 如何获取表和主键,如果表没有主键,如何显示null?
我目前正试图通过在C#中调用以下SQL来检索每个表的表名和主键。这就是我迄今为止所尝试的:C# 如何获取表和主键,如果表没有主键,如何显示null?,c#,sql,sql-server,sql-server-2008,information-schema,C#,Sql,Sql Server,Sql Server 2008,Information Schema,我目前正试图通过在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 =
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”条目。当它工作时,由于某种原因,结果包含“工资”表的副本,如下所示。工资表和员工表都有主键,“测试”表没有:
编辑:我现在已经试过了,而且似乎有效。这样做有什么缺点吗
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
你应该说明你的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
在此查询中,首先处理
表\u约束
和键\u列\u用法
之间的内部联接,并将结果合并到表的左联接视图中。尝试替换此条件约束。约束类型='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
我知道你已经接受了你的答案,但这里有一个纯粹的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程序集的引用,并导入适当的命名空间。这不是他要求的。他希望表的主键中有表名和列名。如果表格没有PK,只显示null。salary
是否还有一个约束?是的,还有一个外键我可以问一下“nvarchar(max)”部分的用途吗?我不完全理解这个问题query@DotNET-Xml路径的将查询转换为Xml流。,type).value('.','nvarchar(max)
位确保结果正确处理Xml实体(例如,和不返回&
)。最后,使用Stuff
函数删除第一个分隔符,它是两个字符:逗号和空格。如果删除该部分,会发生什么情况?请看一下我对这个问题的编辑,看看我有什么想法tried@DotNET-如果您疯狂到在列名称中包含一个verboten Xml字符,如
或&
,则结果中将包含Xml实体(例如
、
或
)。
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();
}