Query del server SQL per ottenere l'elenco di colonne in una tabella insieme ai vincoli Tipi di dati, NOT NULL e PRIMARY KEY


229

Devo scrivere una query su SQL Server per ottenere l'elenco delle colonne in una particolare tabella, i suoi tipi di dati associati (con lunghezza) e se non sono nulli. E sono riuscito a farlo molto.

Ma ora ho anche bisogno di ottenere, nella stessa tabella, contro una colonna - TRUEse quella colonna è una chiave primaria.

Come faccio a fare questo?

La mia uscita prevista è:

Column name | Data type | Length | isnull | Pk

2
Potresti mostrare il codice che hai già?
DOK

Risposte:


478

Per evitare righe duplicate per alcune colonne, utilizzare user_type_id invece di system_type_id.

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')

Sostituisci semplicemente YourTableNamecon il nome della tabella attuale: funziona per SQL Server 2005 e versioni successive.

Nel caso in cui si utilizzano gli schemi, sostituire YourTableName da YourSchemaName.YourTableNamedove YourSchemaNameè il nome attuale schema e YourTableNameè il nome della tabella effettiva.


2
Ciò fornisce lunghezze errate per il tipo di colonne nvarchar, ecc. Fornisce una lunghezza in byte pari al doppio della lunghezza nel tipo di colonna.
Andrew Savinykh,

14
Quelle lunghezze non sono sbagliate - indica la lunghezza dei byte - questa è la massima lunghezza possibile in byte ... se vuoi calcolare lo spazio ecc.,
Questa

2
Funziona benissimo per me SQL Server 2012 :)
Doc Holiday

2
DOVE c.object_id = OBJECT_ID ('YourTableName') .... Avevo bisogno di DOVE c.object_id = OBJECT_ID ('MySchema.MyTableName') e poi tutto ha funzionato bene.
Ivan,

7
Questa query restituisce colonne duplicate se si hanno più indici che coinvolgono la stessa colonna. Per risolvere il problema, sostituire gli ultimi due join con i seguenti: 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

È possibile utilizzare la query:

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

per ottenere tutti i metadati richiesti ad eccezione delle informazioni Pk.


2
l'ho fatto :) Ma ho bisogno anche del PK: |
Shrayas, l'


1
Questo è fantastico perché funziona con versioni SS precedenti al 2005. Grazie!
Karl Hoaglund,

19

In SQL 2012 è possibile utilizzare:

EXEC sp_describe_first_result_set N'SELECT * FROM [TableName]'

Questo ti darà i nomi delle colonne insieme alle loro proprietà.


13

Prova questo:

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

2
In che modo la tua risposta differisce da quella pubblicata da Ajadex? Entrambe le risposte non restituiscono informazioni sulla chiave primaria.
Artemix,

10

Per assicurarti di ottenere la giusta lunghezza dovresti considerare i tipi di unicode come un caso speciale. Vedi il codice sotto.

Per ulteriori informazioni, consultare: 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
il nome DDL è così utile per dynamic-sql che crea tabelle! Grazie!!
George Menoutis,

6

Espandendo la risposta di Alex, puoi farlo per ottenere il vincolo PK

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'

Devo aver perso che vuoi che una bandiera determini se la colonna data faceva parte del PK invece del nome del vincolo PK. Per questo useresti:

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'

bene. Non mi dà il risultato richiesto :(
Shrayas l'

5

wite il nome della tabella nell'editor di query selezionare il nome e premere Alt + F1 e porterà tutte le informazioni della tabella.


Chiede una domanda, ma hai ragione in questo modo ti permette di vedere tutte le informazioni.
Rafa Barragan,

ma ancora; super pulito :-)
netfed

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

Esegui SELECT *l'istruzione precedente per vedere cosa restituisce information_schema.columns.

A questa domanda è stata precedentemente fornita una risposta: https://stackoverflow.com/a/11268456/6169225


se questa domanda ha già ricevuto una risposta, contrassegna il post come duplicato .
Martijn Pieters


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

Lanciando un'altra risposta sul ring, questo ti darà quelle colonne e altro ancora:

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

Per cercare quale colonna si trova in quale tabella in base al tipo di dati di ricerca per tre diverse tabelle in un database. Questa query è espandibile in 'n' tabelle.


2

Trova i risultati della combinazione per Tipo dati e Lunghezza ed è nullable in forma di "NULL" e "Non null". Usa la query di seguito.

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')

troverai il risultato come mostrato sotto.

inserisci qui la descrizione dell'immagine

Grazie.


1
la tua condizione di Vincolo dovrebbe essere il contrario.
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
Utilizza il rientro anziché il markup in linea e aggiungi alcune spiegazioni alla tua risposta.
Toxantron,

Perché ORDER BY 2?
reggaeguitar,

0

inserisci qui la descrizione dell'immagine

Query: EXEC SP_DESCRIBE_FIRST_RESULT_SET N'SELECT ANNUAL_INCOME DA [BSLID2C]. [DBO]. [EMPLOYEE] '

NOTA: IN ALCUNI IDE PRIMA DI SELEZIONARE N FUNZIONA O, IN ALCUNI IDE SENZA N È FUNZIONANTE


0

Non esiste una chiave primaria qui, ma ciò può aiutare altri utenti che desiderano semplicemente avere un nome di tabella con il nome del campo e le proprietà di base del campo

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

Ho appena reso marc_s "presentazione pronta":

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')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.