SQL Server-Abfrage zum Abrufen der Liste der Spalten in einer Tabelle zusammen mit den Einschränkungen Datentypen, NICHT NULL und PRIMARY KEY


229

Ich muss eine Abfrage auf SQL Server schreiben, um die Liste der Spalten in einer bestimmten Tabelle, die zugehörigen Datentypen (mit Länge) und wenn sie nicht null sind, abzurufen. Und ich habe es geschafft, so viel zu tun.

Aber jetzt muss ich auch in derselben Tabelle gegen eine Spalte vorgehen - TRUEwenn diese Spalte ein Primärschlüssel ist.

Wie mache ich das?

Meine erwartete Ausgabe ist:

Column name | Data type | Length | isnull | Pk

2
Könnten Sie den Code anzeigen, den Sie bereits haben?
DOK

Antworten:


478

Verwenden Sie user_type_id anstelle von system_type_id, um doppelte Zeilen für einige Spalten zu vermeiden.

SELECT 
    c.name 'Column Name',
    t.Name 'Data type',
    c.max_length 'Max Length',
    c.precision ,
    c.scale ,
    c.is_nullable,
    ISNULL(i.is_primary_key, 0) 'Primary Key'
FROM    
    sys.columns c
INNER JOIN 
    sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN 
    sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN 
    sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE
    c.object_id = OBJECT_ID('YourTableName')

Ersetzen YourTableNameSie einfach durch Ihren tatsächlichen Tabellennamen - funktioniert für SQL Server 2005 und höher.

Falls Sie Schemata verwenden, ersetzen YourTableName durch , YourSchemaName.YourTableNamewo YourSchemaNamedie tatsächlichen Schemanamen und YourTableNamesind die eigentlichen Tabellennamen.


2
Dies gibt falsche Längen für den Spaltentyp nvarchar usw. an. Es gibt die Bytelänge an, die doppelt so groß ist wie die Länge im Spaltentyp.
Andrew Savinykh

14
Diese Längen sind nicht falsch - es gibt die Bytelänge an - das ist die maximal mögliche Länge in Bytes ... wenn Sie Speicherplatz usw. berechnen möchten, ist dies die Länge, die Sie erhalten möchten ...
marc_s

2
Funktioniert hervorragend für mich SQL Server 2012 :)
Doc Holiday

2
WHERE c.object_id = OBJECT_ID ('YourTableName') .... Ich brauchte WHERE c.object_id = OBJECT_ID ('MySchema.MyTableName') und dann hat alles gut funktioniert.
Ivan

7
Diese Abfrage gibt doppelte Spalten zurück, wenn Sie mehrere Indizes haben, die dieselbe Spalte betreffen. Um dies zu beheben, ersetzen Sie die letzten beiden Verknüpfungen durch die folgenden: LEFT OUTER JOIN sys.index_columns ic LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id ON ic.object_id = c.object_id AND ic.column_id = c.column_id AND i.is_primary_key=1
Razvan Socol


72

Sie könnten die Abfrage verwenden:

select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, 
       NUMERIC_PRECISION, DATETIME_PRECISION, 
       IS_NULLABLE 
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME='TableName'

um alle Metadaten zu erhalten, die Sie benötigen, mit Ausnahme der Pk-Informationen.


2
Ich habe das gemacht :) Aber ich brauche auch die PK: |
Shrayas


1
Das ist großartig, weil es mit SS-Versionen funktioniert, die älter als 2005 sind. Danke!
Karl Hoaglund

19

In SQL 2012 können Sie Folgendes verwenden:

EXEC sp_describe_first_result_set N'SELECT * FROM [TableName]'

Dadurch erhalten Sie die Spaltennamen zusammen mit ihren Eigenschaften.


13

Versuche dies:

select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE 
from INFORMATION_SCHEMA.COLUMNS IC
where TABLE_NAME = 'tablename' and COLUMN_NAME = 'columnname'

2
Wie unterscheidet sich Ihre Antwort von der von Ajadex? Beide Antworten geben keine Primärschlüsselinformationen zurück.
Artemix

10

Um sicherzustellen, dass Sie die richtige Länge erhalten, müssen Sie Unicode-Typen als Sonderfall betrachten. Siehe Code unten.

Weitere Informationen finden Sie unter: https://msdn.microsoft.com/en-us/library/ms176106.aspx

SELECT 
   c.name 'Column Name',
   t.name,
   t.name +
   CASE WHEN t.name IN ('char', 'varchar','nchar','nvarchar') THEN '('+

             CASE WHEN c.max_length=-1 THEN 'MAX'

                  ELSE CONVERT(VARCHAR(4),

                               CASE WHEN t.name IN ('nchar','nvarchar')

                               THEN  c.max_length/2 ELSE c.max_length END )

                  END +')'

          WHEN t.name IN ('decimal','numeric')

                  THEN '('+ CONVERT(VARCHAR(4),c.precision)+','

                          + CONVERT(VARCHAR(4),c.Scale)+')'

                  ELSE '' END

   as "DDL name",
   c.max_length 'Max Length in Bytes',
   c.precision ,
   c.scale ,
   c.is_nullable,
   ISNULL(i.is_primary_key, 0) 'Primary Key'
FROM    
   sys.columns c
INNER JOIN 
   sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN 
   sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN 
   sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE
   c.object_id = OBJECT_ID('YourTableName')

1
Der DDL-Name ist SO nützlich für Dynamic-SQL, das Tabellen erstellt! Vielen Dank!!
George Menoutis

6

Wenn Sie Alex 'Antwort erweitern, können Sie dies tun, um die PK-Einschränkung zu erhalten

Select C.COLUMN_NAME, C.DATA_TYPE, C.CHARACTER_MAXIMUM_LENGTH, C.NUMERIC_PRECISION, C.IS_NULLABLE, TC.CONSTRAINT_NAME
From INFORMATION_SCHEMA.COLUMNS As C
    Left Join INFORMATION_SCHEMA.TABLE_CONSTRAINTS As TC
      On TC.TABLE_SCHEMA = C.TABLE_SCHEMA
          And TC.TABLE_NAME = C.TABLE_NAME
          And TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
Where C.TABLE_NAME = 'Table'

Ich muss übersehen haben, dass Sie möchten, dass ein Flag anstelle des Namens der PK-Einschränkung feststellt, ob die angegebene Spalte Teil der PK war. Dafür würden Sie verwenden:

Select C.COLUMN_NAME, C.DATA_TYPE, C.CHARACTER_MAXIMUM_LENGTH
    , C.NUMERIC_PRECISION, C.NUMERIC_SCALE
    , C.IS_NULLABLE
    , Case When Z.CONSTRAINT_NAME Is Null Then 0 Else 1 End As IsPartOfPrimaryKey
From INFORMATION_SCHEMA.COLUMNS As C
    Outer Apply (
                Select CCU.CONSTRAINT_NAME
                From INFORMATION_SCHEMA.TABLE_CONSTRAINTS As TC
                    Join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE As CCU
                        On CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
                Where TC.TABLE_SCHEMA = C.TABLE_SCHEMA
                    And TC.TABLE_NAME = C.TABLE_NAME
                    And TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
                    And CCU.COLUMN_NAME = C.COLUMN_NAME
                ) As Z
Where C.TABLE_NAME = 'Table'

Gut. Es gibt mir nicht das erforderliche Ergebnis :(
Shrayas

5

Wählen Sie mit dem Tabellennamen im Abfrageeditor den Namen aus und drücken Sie Alt + F1. Daraufhin werden alle Informationen der Tabelle angezeigt.


Er bittet um eine Anfrage, aber Sie haben Recht, so können Sie alle Informationen sehen.
Rafa Barragan

aber dennoch; super ordentlich :-)
netfed

4
SELECT COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM information_schema.columns WHERE table_name = '<name_of_table_or_view>'

Führen Sie SELECT *die obige Anweisung aus, um zu sehen, was information_schema.columns zurückgibt.

Diese Frage wurde bereits beantwortet - https://stackoverflow.com/a/11268456/6169225


Wenn diese Frage bereits beantwortet wurde, kennzeichnen Sie den Beitrag als Duplikat .
Martijn Pieters

4

Ich bin ein bisschen überrascht, dass niemand etwas erwähnt hat

sp_help 'mytable'

3
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES 
     WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'Table')
      BEGIN
        SELECT COLS.COLUMN_NAME, COLS.DATA_TYPE, COLS.CHARACTER_MAXIMUM_LENGTH, 
              (SELECT 'Yes' FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU
                              ON COLS.TABLE_NAME = TC.TABLE_NAME 
                             AND TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
                             AND KCU.TABLE_NAME = TC.TABLE_NAME
                             AND KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
                             AND KCU.COLUMN_NAME = COLS.COLUMN_NAME) AS KeyX
        FROM INFORMATION_SCHEMA.COLUMNS COLS WHERE TABLE_NAME = 'Table' ORDER BY KeyX DESC, COLUMN_NAME
      END

3

Wenn Sie eine weitere Antwort in den Ring werfen, erhalten Sie folgende Spalten und mehr:

SELECT col.TABLE_CATALOG AS [Database]
     , col.TABLE_SCHEMA AS Owner
     , col.TABLE_NAME AS TableName
     , col.COLUMN_NAME AS ColumnName
     , col.ORDINAL_POSITION AS OrdinalPosition
     , col.COLUMN_DEFAULT AS DefaultSetting
     , col.DATA_TYPE AS DataType
     , col.CHARACTER_MAXIMUM_LENGTH AS MaxLength
     , col.DATETIME_PRECISION AS DatePrecision
     , CAST(CASE col.IS_NULLABLE
                WHEN 'NO' THEN 0
                ELSE 1
            END AS bit)AS IsNullable
     , COLUMNPROPERTY(OBJECT_ID('[' + col.TABLE_SCHEMA + '].[' + col.TABLE_NAME + ']'), col.COLUMN_NAME, 'IsIdentity')AS IsIdentity
     , COLUMNPROPERTY(OBJECT_ID('[' + col.TABLE_SCHEMA + '].[' + col.TABLE_NAME + ']'), col.COLUMN_NAME, 'IsComputed')AS IsComputed
     , CAST(ISNULL(pk.is_primary_key, 0)AS bit)AS IsPrimaryKey
  FROM INFORMATION_SCHEMA.COLUMNS AS col
       LEFT JOIN(SELECT SCHEMA_NAME(o.schema_id)AS TABLE_SCHEMA
                      , o.name AS TABLE_NAME
                      , c.name AS COLUMN_NAME
                      , i.is_primary_key
                   FROM sys.indexes AS i JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
                                                                     AND i.index_id = ic.index_id
                                         JOIN sys.objects AS o ON i.object_id = o.object_id
                                         LEFT JOIN sys.columns AS c ON ic.object_id = c.object_id
                                                                   AND c.column_id = ic.column_id
                  WHERE i.is_primary_key = 1)AS pk ON col.TABLE_NAME = pk.TABLE_NAME
                                                  AND col.TABLE_SCHEMA = pk.TABLE_SCHEMA
                                                  AND col.COLUMN_NAME = pk.COLUMN_NAME
 WHERE col.TABLE_NAME = 'YourTableName'
   AND col.TABLE_SCHEMA = 'dbo'
 ORDER BY col.TABLE_NAME, col.ORDINAL_POSITION;

2
select
      c.name as [column name], 
      t.name as [type name],
      tbl.name as [table name]
from sys.columns c
         inner join sys.types t 
      on c.system_type_id = t.system_type_id 
         inner join sys.tables tbl
      on c.object_id = tbl.object_id
where
      c.object_id = OBJECT_ID('YourTableName1') 
          and 
      t.name like '%YourSearchDataType%'
union
(select
      c.name as [column name], 
      t.name as [type name],
      tbl.name as [table name]
from sys.columns c
         inner join sys.types t 
      on c.system_type_id = t.system_type_id 
         inner join sys.tables tbl
      on c.object_id = tbl.object_id
where
      c.object_id = OBJECT_ID('YourTableName2') 
          and 
      t.name like '%YourSearchDataType%')
union
(select
      c.name as [column name], 
      t.name as [type name],
      tbl.name as [table name]
from sys.columns c
         inner join sys.types t 
      on c.system_type_id = t.system_type_id 
         inner join sys.tables tbl
      on c.object_id = tbl.object_id
where
      c.object_id = OBJECT_ID('YourTableName3') 
          and 
      t.name like '%YourSearchDataType%')
order by tbl.name

Suchen Sie anhand Ihres Suchdatentyps nach drei verschiedenen Tabellen in einer Datenbank, welche Spalte sich in welcher Tabelle befindet. Diese Abfrage kann auf 'n' Tabellen erweitert werden.


2

Das Kombinationsergebnis für Datentyp und Länge finden und kann in Form von "NULL" und "Nicht null" auf Null gesetzt werden. Verwenden Sie die folgende Abfrage.

SELECT c.name AS 'Column Name',
       t.name + '(' + cast(c.max_length as varchar(50)) + ')' As 'DataType',
       case 
         WHEN  c.is_nullable = 0 then 'null' else 'not null'
         END AS 'Constraint'
  FROM sys.columns c
  JOIN sys.types t
    ON c.user_type_id = t.user_type_id
 WHERE c.object_id    = Object_id('TableName')

Sie finden das Ergebnis wie unten gezeigt.

Geben Sie hier die Bildbeschreibung ein

Danke dir.


1
Ihr Zustand der Einschränkung sollte umgekehrt sein.
Allen

0
SELECT  
   T.NAME AS [TABLE NAME]
   ,C.NAME AS [COLUMN NAME]
   ,P.NAME AS [DATA TYPE]
   ,P.MAX_LENGTH AS [Max_SIZE]
   ,C.[max_length] AS [ActualSizeUsed]
   ,CAST(P.PRECISION AS VARCHAR) +'/'+ CAST(P.SCALE AS VARCHAR) AS [PRECISION/SCALE]
FROM SYS.OBJECTS AS T
JOIN SYS.COLUMNS AS C
    ON T.OBJECT_ID = C.OBJECT_ID
JOIN SYS.TYPES AS P
    ON C.SYSTEM_TYPE_ID = P.SYSTEM_TYPE_ID
    AND C.[user_type_id] = P.[user_type_id]
WHERE T.TYPE_DESC='USER_TABLE'
  AND T.name = 'InventoryStatus'
ORDER BY 2

1
Bitte verwenden Sie Einrückung anstelle von Inline-Markup und fügen Sie Ihrer Antwort eine Erklärung hinzu.
Toxantron

Warum mit 2 bestellen?
Reggaeguitar

0

Geben Sie hier die Bildbeschreibung ein

Abfrage: EXEC SP_DESCRIBE_FIRST_RESULT_SET N'SELECT ANNUAL_INCOME FROM [BSLID2C]. [DBO]. [EMPLOYEE] '

HINWEIS: IN EINIGER IDE, BEVOR SELECT N FUNKTIONIERT ODER IN EINIGER IDE OHNE N FUNKTIONIERT


0

Hier gibt es keinen Primärschlüssel, aber dies kann anderen Benutzern helfen, die nur einen Tabellennamen mit Feldnamen und grundlegenden Feldeigenschaften haben möchten

USE [**YourDB**]
GO
SELECT tbl.name, fld.[Column Name],fld.[Constraint],fld.DataType 
FROM sys.all_objects as tbl left join 
(SELECT c.OBJECT_ID,  c.name AS 'Column Name',
       t.name + '(' + cast(c.max_length as varchar(50)) + ')' As 'DataType',
       case 
         WHEN  c.is_nullable = 0 then 'null' else 'not null'
         END AS 'Constraint'
  FROM sys.columns c
  JOIN sys.types t
    ON c.user_type_id = t.user_type_id
) as fld on tbl.OBJECT_ID = fld.OBJECT_ID
WHERE ( tbl.[type]='U' and tbl.[is_ms_shipped] = 0)
ORDER BY tbl.[name],fld.[Column Name]
GO

-1

Ich habe gerade marc_s "Präsentation fertig" gemacht:

SELECT 
    c.name 'Column Name',
    t.name 'Data type',
    IIF(t.name = 'nvarchar', c.max_length / 2, c.max_length) 'Max Length',
    c.precision 'Precision',
    c.scale 'Scale',
    IIF(c.is_nullable = 0, 'No', 'Yes') 'Nullable',
    IIF(ISNULL(i.is_primary_key, 0) = 0, 'No', 'Yes') 'Primary Key'
FROM    
    sys.columns c
INNER JOIN 
    sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN 
    sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN 
    sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE
    c.object_id = OBJECT_ID('YourTableName')
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.