3

現在、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" テーブルにはありません。

3番目のレコードを削除するにはどうすればよいですか?

編集:私は今これを試しましたが、うまくいくようです。そうすることのデメリットはありますか?

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 
4

4 に答える 4

2

この条件を置き換えてみてください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 
于 2012-09-10T19:20:01.693 に答える
1

あなたはすでにあなたの答えを受け入れているようですが、誰かが興味を持っている場合に備えて、純粋な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アセンブリへの参照を追加し、適切な名前空間をインポートする必要があります。

于 2012-09-10T20:30:27.870 に答える
1

複数の列を持つ 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 

ところで、TABLES ビューへの結合を本当に使用したい場合は、結合をネストする必要があります。問題は、2 つの外部結合があり、外部キーからの列が出力に行を生成していることです。前述のサブクエリ アプローチに対する次のアプローチの欠点は、主キーが複数の列で構成されている場合に複数の行を取得することです。つまり、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最初に処理され、結果が左結合に結合されてTABLES表示されます。

于 2012-09-10T19:08:37.933 に答える
0
select
  TABLE_SCHEMA, 
  TABLE_NAME 
from 
  INFORMATION_SCHEMA.TABLES
where 
  objectproperty(object_id(table_name),'TableHasPrimaryKey')=0
ORDER BY 
  TABLE_NAME
于 2012-09-10T19:03:00.443 に答える