Consulta do servidor SQL para obter a lista de colunas em uma tabela, juntamente com as restrições Tipos de dados, NOT NULL e PRIMARY KEY

229

Preciso escrever uma consulta no SQL Server para obter a lista de colunas em uma tabela específica, seus tipos de dados associados (com comprimento) e se não forem nulos. E eu consegui fazer isso muito.

Mas agora eu também preciso obter, na mesma tabela, uma coluna - TRUEse essa coluna for uma chave primária.

Como eu faço isso?

Minha saída esperada é:

Column name | Data type | Length | isnull | Pk
Shrayas
fonte
2
Você poderia mostrar o código que já possui?
DOK

Respostas:

478

Para evitar linhas duplicadas para algumas colunas, use user_type_id em vez de 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')

Apenas substitua YourTableNamepelo nome da tabela atual - funciona para o SQL Server 2005 e versões posteriores.

Caso esteja usando esquemas, substitua YourTableName por YourSchemaName.YourTableNameonde YourSchemaNameestá o nome do esquema real eYourTableName o nome da tabela real.

marc_s
fonte
2
Isso fornece comprimentos incorretos para o tipo de colunas nvarchar etc. Fornece o comprimento do byte que é o dobro do comprimento no tipo de coluna.
Andrew Savinykh
14
Esses comprimentos são não é errado - ela dá o comprimento de bytes - que é o comprimento máximo possível em bytes ... se você quer espaço calcular etc., que é o comprimento que você deseja obter ....
marc_s
2
Funciona muito bem para mim, o SQL Server 2012 :) #
21815 Doc Holiday
2
WHERE c.object_id = OBJECT_ID ('YourTableName') .... Eu precisava de WHERE c.object_id = OBJECT_ID ('MySchema.MyTableName') e tudo funcionou bem.
Ivan
7
Essa consulta retornará colunas duplicadas se você tiver vários índices envolvendo a mesma coluna. Para corrigi-lo, substitua as duas últimas junções pelo seguinte: 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
95

O procedimento armazenado sp_columns retorna informações detalhadas da tabela.

exec sp_columns MyTable
descompilado
fonte
2
exec sp_pkeys exec sp_fkeys
Leonardo Marques de Souza
2
consulta curta, mas faz um grande trabalho.
Akshay Chawla
1
resposta concisa agradável
t_warsop
72

Você pode usar a consulta:

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

para obter todos os metadados necessários, exceto as informações de Pk.

Ajadex
fonte
2
Eu fiz isso :) Mas também preciso do PK: |
Shrayas 11/03/10
msdn.microsoft.com/pt-br/library/ms189813(v=sql.120).aspx sp_fkeys sp_pkeys
Marques Leonardo de Souza
1
Isso é ótimo porque funciona com versões SS anteriores a 2005. Obrigado!
Karl Hoaglund
19

No SQL 2012, você pode usar:

EXEC sp_describe_first_result_set N'SELECT * FROM [TableName]'

Isso fornecerá os nomes das colunas, juntamente com suas propriedades.

Amruta Kar
fonte
13

Tente o seguinte:

select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE 
from INFORMATION_SCHEMA.COLUMNS IC
where TABLE_NAME = 'tablename' and COLUMN_NAME = 'columnname'
khaleel
fonte
2
Como sua resposta difere da postada pela Ajadex? Ambas as respostas não retornam informações da Chave Primária.
Artemix 23/11/2012
10

Para garantir que você obtenha o comprimento certo, seria necessário considerar os tipos unicode como um caso especial. Veja o código abaixo.

Para obter mais informações, consulte: 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')
Desenvolvedor Microsoft
fonte
1
o nome DDL é tão útil para o sql dinâmico que cria tabelas! Obrigado!!
George Menoutis
6

Expandindo a resposta de Alex, você pode fazer isso para obter a restrição 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 ter perdido que você deseja que um sinalizador determine se a coluna especificada fazia parte da PK em vez do nome da restrição PK. Para isso você usaria:

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'
Thomas
fonte
bem. Não me fornece o resultado necessário :(
Shrayas
5

Com o nome da tabela no editor de consultas, selecione o nome e pressione Alt + F1 e ele trará todas as informações da tabela.

Abu Zafor
fonte
Ele pede uma consulta, mas você está certo dessa maneira, permitindo que você veja todas as informações.
21416 Rafa Barragan
mas ainda; super arrumado :-)
netfed
4
SELECT COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM information_schema.columns WHERE table_name = '<name_of_table_or_view>'

Execute SELECT *na instrução acima para ver o que information_schema.columns retorna.

Esta pergunta foi respondida anteriormente - https://stackoverflow.com/a/11268456/6169225

Marquistador
fonte
se essa pergunta já tiver sido respondida, sinalize a postagem como duplicada .
Martijn Pieters
4

Estou um pouco surpreso que ninguém mencionou

sp_help 'mytable'
Mario Levesque
fonte
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
Pete vM
fonte
3

Jogando outra resposta no ringue, você fornecerá essas colunas e muito mais:

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;
JustinStolle
fonte
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

Para pesquisar qual coluna está em qual tabela, com base no seu tipo de dados de pesquisa, encontra três tabelas diferentes em um banco de dados. Esta consulta é expansível para 'n' tabelas.

mtinyavuz
fonte
2

Encontre resultado combinado para Tipo de dados e Comprimento e é anulável na forma de "NULL" e "Não nulo" Use a consulta abaixo.

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

você encontrará o resultado como mostrado abaixo.

insira a descrição da imagem aqui

Obrigado.

Ankit Mori
fonte
1
sua condição de restrição deve ser o contrário.
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
Rajiv Singh
fonte
1
Use recuo em vez de marcação embutida e adicione algumas explicações à sua resposta.
Toxantron
Por que ordem de 2?
Reggaeguitar
0

insira a descrição da imagem aqui

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

NOTA: EM ALGUM IDE, ANTES DE SELECIONAR N, ESTÁ FUNCIONANDO OU, EM ALGUM IDE, SEM N, ESTÁ FUNCIONANDO

Abdullah Pariyani
fonte
0

Não há chave primária aqui, mas isso pode ajudar outros usuários que gostariam de ter um nome de tabela com o nome do campo e as propriedades básicas do 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
Suhail Abdul Rehman Chougule
fonte
-1

Acabei de fazer a marc_s "apresentação 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')
krs
fonte