Veri türleri, NOT NULL ve PRIMARY KEY kısıtlamaları ile birlikte bir tablodaki sütunların listesini almak için SQL sunucu sorgusu


229

Belirli bir tablo, ilişkili veri türleri (uzunluğu ile) sütun listesi ve boş değilse, SQL sunucusunda bir sorgu yazmak gerekiyor. Ve bunu çok yapmayı başardım.

Ama şimdi de aynı tabloda, bir sütuna karşı almam gerekiyor - TRUEbu sütun birincil bir anahtar ise.

Bunu nasıl yaparım?

Beklediğim çıktı:

Column name | Data type | Length | isnull | Pk

2
Zaten sahip olduğunuz kodu gösterebilir misiniz?
DOK

Yanıtlar:


478

Bazı sütunlar için yinelenen satırları önlemek için system_type_id yerine user_type_id öğesini kullanın.

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

Sadece YourTableNamegerçek tablo adınızla değiştirin - SQL Server 2005 ve üstü için çalışır.

Eğer şemaları kullandığınız durumda, yerine YourTableName göre YourSchemaName.YourTableNamenerede YourSchemaNamegerçek şema adıdır ve YourTableNamegerçek tablo adıdır.


2
Bu, nvarchar, vb. Tip sütunlar için yanlış uzunluklar verir. Sütun türündeki uzunluğun iki katı olan bayt uzunluğunu verir.
Andrew Savinykh

14
Bu uzunluklar yanlış değil - bayt uzunluğunu veriyor - bayt cinsinden mümkün olan maksimum uzunluk ... alan vb. Hesaplamak istiyorsanız, almak istediğiniz uzunluk budur ....
marc_s

2
Benim için harika çalışıyor SQL Server 2012 :)
Doc Holiday

2
NEREDE c.object_id = OBJECT_ID ('YourTableName') .... NEREYE ihtiyacım var c.object_id = OBJECT_ID ('MySchema.MyTableName') ve sonra her şey iyi çalıştı.
Ivan

7
Aynı sütunu içeren birden çok dizininiz varsa, bu sorgu yinelenen sütunları döndürür. Düzeltmek için, son iki birleşimi aşağıdaki ile değiştirin: 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

Sorguyu kullanabilirsiniz:

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

Pk bilgileri hariç tüm meta verileri almak için.


2
Bunu yaptım :) Ama ben de PK gerekir: |
Shrayas


1
Bu harika çünkü 2005'ten daha eski SS sürümleriyle çalışıyor. Teşekkürler!
Karl Hoaglund

19

SQL 2012'de şunları kullanabilirsiniz:

EXEC sp_describe_first_result_set N'SELECT * FROM [TableName]'

Bu, sütun adlarını özellikleriyle birlikte verir.


13

Bunu dene:

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

2
Cevabınız Ajadex tarafından gönderilen cevaptan ne anlama geliyor? Her iki yanıt da Birincil Anahtar bilgilerini döndürmez.
Artemix

10

Doğru uzunluğu elde etmenizi sağlamak için unicode tiplerini özel bir durum olarak düşünmeniz gerekir. Aşağıdaki koda bakınız.

Daha fazla bilgi için bkz. 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
DDL Adı tabloları oluşturan dinamik sql için çok yararlıdır! Teşekkürler!!
George Menoutis

6

Alex'in cevabına genişleyerek, PK kısıtlamasını almak için bunu yapabilirsiniz

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'

Belirtilen sütunun PK kısıtlamasının adı yerine PK'nın bir parçası olup olmadığını belirlemek için bir bayrak istediğinizi kaçırmış olmalıyım. Bunun için şunları kullanırsınız:

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'

iyi. Bana gerekli sonucu
vermiyor

5

sorgu düzenleyicide tablo adını wite adı seçin ve Alt + F1 tuşlarına basın, tablonun tüm bilgilerini getirecektir.


Bir sorgu istiyor, ama haklısın bu şekilde tüm bilgileri görmene izin veriyor.
Rafa Barragan

ama hala; süper temiz :-)
netfed

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

SELECT *Hangi bilginin sch_schema.columns döndürdüğünü görmek için yukarıdaki ifadede çalıştırın .

Bu soru daha önce cevaplanmıştır - https://stackoverflow.com/a/11268456/6169225


bu soru zaten yanıtlandıysa, yayını yinelenen olarak işaretleyin .
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

Halkaya başka bir cevap atmak, bu size şu sütunları ve daha fazlasını verecektir:

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

Bir veritabanında üç farklı tablo için arama veri türünüzü temel alarak hangi sütunun hangi tabloda olduğunu aramak için. Bu sorgu 'n' tablolarına genişletilebilir.


2

Datatype ve Length için birleştirme sonucunu bulun ve "NULL" ve "Not null" biçiminde boş bırakılabilir. Aşağıdaki sorguyu kullanın.

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

sonucu aşağıda gösterildiği gibi bulacaksınız.

resim açıklamasını buraya girin

Teşekkür ederim.


1
Kısıtlama durumunuz tam tersi olmalıdır.
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
Lütfen satır içi İşaretleme yerine girinti kullanın ve yanıtınıza biraz açıklama ekleyin.
Toxantron

Neden SİPARİŞ 2?
reggaeguitar

0

resim açıklamasını buraya girin

Sorgu: [BSLID2C]. [DBO] 'dan EXEC SP_DESCRIBE_FIRST_RESULT_SET N'SELECT YILLIK_INCOME. [DBO]. [EMPLOYEE]'

NOT: SEÇME SEÇMEDEN ÖNCE BAZI IDE'DE VEYA N OLMADAN BAZI IDE'DE ÇALIŞIR


0

Burada birincil anahtar yoktur, ancak bu yalnızca alan adı ve temel alan özelliklerine sahip bir tablo adına sahip olmak isteyen diğer kullanıcılara yardımcı olabilir

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

Ben sadece marc_s "sunum hazır":

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')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.