Запит SQL-сервера для отримання списку стовпців таблиці разом із типами даних, а не обмеженнями NULL та PRIMARY KEY


229

Мені потрібно написати запит на SQL-сервер, щоб отримати список стовпців у певній таблиці, пов’язані з ними типи даних (з довжиною) і якщо вони недійсні. І мені це вдалося зробити дуже багато.

Але тепер мені також потрібно потрапити в цю ж таблицю проти стовпця - TRUEякщо цей стовпчик є первинним ключем.

Як це зробити?

Мій очікуваний вихід:

Column name | Data type | Length | isnull | Pk

2
Чи можете ви показати код, який у вас уже є?
DOK

Відповіді:


478

Щоб уникнути повторюваних рядків для деяких стовпців, використовуйте user_type_id замість 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')

Просто замініть YourTableNameфактичним назвою таблиці - працює для SQL Server 2005 і новіших версій.

Якщо ви використовуєте схеми, замініть YourTableName на те, YourSchemaName.YourTableNameде YourSchemaNameє власне ім'я схеми та YourTableNameвласне ім'я таблиці.


2
Це дає неправильну довжину для nvarchar тощо типу стовпців. Він дає довжину байтів, яка вдвічі більша за довжину в типі стовпців.
Андрій Савіних

14
Ці довжини не є помилковими - це дає довжину байтів - це максимально можлива довжина в байтах ... якщо ви хочете обчислити простір і т. Д., Це довжина, яку ви хочете отримати ....
marc_s

2
Для мене чудово працює SQL Server 2012 :)
Doc Holiday

2
ДЕ c.object_id = OBJECT_ID ('YourTableName') .... Мені потрібен був WHERE c.object_id = OBJECT_ID ('MySchema.MyTableName'), і тоді все працювало нормально.
Іван

7
Цей запит повертає повторювані стовпці, якщо у вас є кілька індексів, що містять один і той же стовпець. Щоб виправити це, замініть останні два об'єднання на наступне: 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
Разван Сокол


72

Ви можете використовувати запит:

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

щоб отримати всі необхідні вам метадані, крім інформації про ПК.


2
Я це зробив :) Але мені потрібен і ПК: |
Шраяс


1
Це чудово, оскільки він працює з версіями SS, старшими за 2005 р. Дякую!
Карл Хоглунд

19

У SQL 2012 ви можете використовувати:

EXEC sp_describe_first_result_set N'SELECT * FROM [TableName]'

Це дасть вам назви стовпців разом із їх властивостями.


13

Спробуйте це:

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

2
Чим ваша відповідь відрізняється від тієї, яку опублікував Ajadex? Обидві відповіді не повертають інформацію про первинний ключ.
Артемікс

10

Щоб отримати правильну довжину, вам слід розглянути типи Unicode як особливий випадок. Дивіться код нижче.

Для отримання додаткової інформації див: 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 настільки корисна для динамічного sql, який створює таблиці! Дякую!!
Джордж Менутіс

6

Розширюючи відповідь Алекса, ви можете зробити це, щоб отримати обмеження ПК

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'

Я, мабуть, пропустив, що ви хочете, щоб прапор визначав, чи вказаний стовпець був частиною ПК замість імені обмеження ПК. Для цього ви б використали:

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'

Ну. Це не дає мені необхідного результату :(
Шрайас

5

біле ім'я таблиці в редакторі запитів виберіть ім'я та натисніть Alt + F1, і воно принесе всю інформацію таблиці.


Він запитує запит, але ви маєте рацію. Цей спосіб дозволяє вам бачити всю інформацію.
Рафа Барраган

але все ж; супер акуратне :-)
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 *у наведеному вище твердженні, щоб побачити, що повертається інформація_schema.column.

На це питання раніше відповіли - https://stackoverflow.com/a/11268456/6169225


якщо на це питання вже відповіли, позначте його як дублікат .
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

Вкинувши ще одну відповідь у дзвінок, ви отримаєте ці стовпці та інше:

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

Для пошуку, який стовпець в якій таблиці, на основі типу ваших пошукових даних для трьох різних таблиць в одній базі даних. Цей запит можна розширити до 'n' таблиць.


2

Знайдіть результат комбінування для типу "Тип" та "Довжина" і зводиться до нуля у вигляді "NULL" та "Not null" Використовуйте нижче за запитом.

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

ви знайдете результат, як показано нижче.

введіть тут опис зображення

Дякую.


1
ваш стан обмеження має бути навпаки.
Аллен

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
Будь ласка, використовуйте відступ замість вбудованої розмітки та додайте пояснення до своєї відповіді.
Токсантрон

Чому ЗАМОВИТИ 2?
регейгутар

0

введіть тут опис зображення

Запит: EXEC SP_DESCRIBE_FIRST_RESULT_SET N'SELECT ANNUAL_INCOME ОТ [BSLID2C]. [DBO]. [EMPLOYEE] '

ПРИМІТКА: У ДЕЯКІЙ ІДЕЇ ДО ВИБОРУ НЕ РОБОТАЄ АБО, У НЕЧОМОЇ ІДЕЇ БЕЗ НЕ ПРАЦЮЄ


0

Тут немає первинного ключа, але це може допомогти іншим користувачам, які просто хотіли б мати ім’я таблиці з назвою поля та основними властивостями поля

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

Я щойно зробив marc_s "готову презентацію":

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')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.