繁体   English   中英

如何获取表和主键,如果表没有主键,则显示null?

[英]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_CONSTRAINTSKEY_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM