在SQL Server中,“describe table”相当于什么?

412

我有一个SQL Server数据库,想知道它有哪些列和数据类型。我更倾向于通过查询来完成这个任务而不是使用Enterprise Manager等GUI工具。有没有一种方法可以做到这一点?


1
另一个stackoverflow问题已经解答了这个问题。 - Shiva
我不明白为什么微软之前没有放置这个选项。这是必备的功能。 - nomadSK25
24个回答

445

你可以使用 sp_columns 存储过程:

exec sp_columns MyTable

2
谢谢 - 我正要发布同样的问题,只不过是用 T-SQL 而不是 MSSQL。 - Jedidja
17
请注意:不要将表名用引号括起来,也不要使用 TableOwner.TableName 的语法。请直接书写表名。 - Gezim
2
如果您运行此查询时没有结果,请单击此处查看解决方法。 - mlissner
22
如果不想使用存储过程,可以使用以下语句来查询名为'TABLENAME'的表的所有列信息:使用Select * From INFORMATION_SCHEMA.COLUMNS Where TABLE_NAME = 'TABLENAME' - Matias Elorriaga
4
在使用sqlcmd进行查询时,sp_columns输出的结果令人难以阅读,即使使用了巨大的终端宽度也无济于事。下面给出的使用select语句的解决方案更加适合sqlcmd用户。 - ctpenrose
显示剩余4条评论

164

获取表的元数据有几种方法:

EXEC sp_help tablename

将返回多个结果集,描述表格、其列和约束。

INFORMATION_SCHEMA 视图可以提供所需信息,但不幸的是必须手动查询视图并进行联接。


9
对我来说,没有使用“@”符号也能够正常运行。执行 EXEC sp_help 'table_name'。 - Ali
这是对Viranja答案的更正版本。然而,@是不正确的语法。 - pcnate
看起来@tablename是示例中的一个变量。该存储过程可以双向使用,无论是字符串还是“普通”的表名(exec sp_help Employeesexec sp_help 'Employees')。 - KekuSemau
请注意:模式(甚至是数据库)可以放在反引号中:execute sp_help 'db.sch.your_table' - ColinMac

74

如果您不想使用存储过程,这里有一个简单的查询版本。

select * 
  from information_schema.columns 
 where table_name = 'aspnet_Membership'
 order by ordinal_position

1
在我的情况下,即使由于某些原因,那些存储过程不可用也适用。 - James Mills
存储过程非常死板,对于像我这样的 SQLCMD 初学者来说非常不友好。 - ctpenrose
喜欢这个,因为它按名称排序:D - Marin
这非常适合在Pyspark中使用! - Javier Ruiz

53
你可以使用以下命令:sp_help tablename 示例:sp_help Customer 或使用快捷键:
- 选择所需的表格,然后按下ALT+F1 示例:选中Customer表格,按下ALT+F1

请注意,如果您的表位于用户定义的模式中,则应从查询中排除它。所有包含此名称表的模式将出现在结果集中名为“TABLE_OWNER”的列中。 - Buggieboy
请注意,为了使快捷方式起作用,必须完全选择表/视图/过程。SSMS不会自动展开选择(我本来期望它会这样做)。可以使用“Ctrl+W”来展开选择并选择整个名称。 - bugybunny

31

使用此查询。

Select * From INFORMATION_SCHEMA.COLUMNS Where TABLE_NAME = 'TABLENAME'

2
如果你先说“use MyDatabase”,那对我来说是可以工作的。 - Jason D
我喜欢这个,因为它也适用于MySQL,所以我不必在我的代码中更改SQL。 - Honinbo Shusaku
4
这个回答和5年前的 https://dev59.com/FXRC5IYBdhLWcg3wXP0C#319424 没有任何区别。我认为重复的回答没有用处。 - Jason S

20

除了其他答案中展示的方法外,您还可以使用

SELECT TOP 0 * FROM table_name

这将为您提供每个没有结果的列的名称,并在极小的开销下几乎立即完成。


1
TOP 1 会提供一个示例数据,这可能更具说明性。 - Spurgeon

15
请使用以下的SQL查询语句,这对我的情况起作用了。
select * FROM   INFORMATION_SCHEMA.Columns where table_name = 'tablename';

3
2008年和2014年已经给出了同样的答案。我认为重复的答案没有什么用处。 - Jason S

13

只需选择表格并按下Alt+F1,它会显示有关表格的所有信息,例如列名、数据类型、键等。


11
OP要求一种无需GUI的方法。 - Spikolynn
-1,因为2014年已经有另一个用户给出了相同的建议。请尊重他人的时间。 - Alexander Malakhov

9

SQL Server中与Oracle的describe命令相当的是存储过程sp_help

describe命令可以提供关于列名、类型、长度等信息。

在SQL Server中,假设您想要描述数据库“mydb”中模式为“myschema”的表格“mytable”,您可以执行以下操作:

USE mydb;
exec sp_help 'myschema.mytable';

7

我写了一个类似于t-sql的sql*plus DESC(RIBE)语句(会显示列注释),如下:

USE YourDB
GO

DECLARE @objectName NVARCHAR(128) = 'YourTable';

SELECT
  a.[NAME]
 ,a.[TYPE]
 ,a.[CHARSET]
 ,a.[COLLATION]
 ,a.[NULLABLE]
 ,a.[DEFAULT]
 ,b.[COMMENTS]
-- ,a.[ORDINAL_POSITION]
FROM
  (
    SELECT
      COLUMN_NAME                                     AS [NAME]
     ,CASE DATA_TYPE
        WHEN 'char'       THEN DATA_TYPE  + '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')'
        WHEN 'numeric'    THEN DATA_TYPE  + '(' + CAST(NUMERIC_PRECISION AS VARCHAR) + ', ' + CAST(NUMERIC_SCALE AS VARCHAR) + ')'
        WHEN 'nvarchar'   THEN DATA_TYPE  + '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')'
        WHEN 'varbinary'  THEN DATA_TYPE + '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')'
        WHEN 'varchar'    THEN DATA_TYPE   + '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')'
        ELSE DATA_TYPE
      END                                             AS [TYPE]
     ,CHARACTER_SET_NAME                              AS [CHARSET]
     ,COLLATION_NAME                                  AS [COLLATION]
     ,IS_NULLABLE                                     AS [NULLABLE]
     ,COLUMN_DEFAULT                                  AS [DEFAULT]
     ,ORDINAL_POSITION
    FROM   
      INFORMATION_SCHEMA.COLUMNS
    WHERE
      TABLE_NAME = @objectName
  ) a
  FULL JOIN
  (
   SELECT
     CAST(value AS NVARCHAR)                        AS [COMMENTS]
    ,CAST(objname AS NVARCHAR)                      AS [NAME]
   FROM
     ::fn_listextendedproperty ('MS_Description', 'user', 'dbo', 'table', @objectName, 'column', default)
  ) b
  ON a.NAME COLLATE YourCollation = b.NAME COLLATE YourCollation
ORDER BY
  a.[ORDINAL_POSITION];

上述的select语句可以用于一个标记为存储过程的系统中,并且可以通过简单的方式从实例中的任何数据库中调用:
USE master;
GO

IF OBJECT_ID('sp_desc', 'P') IS NOT NULL
  DROP PROCEDURE sp_desc
GO

CREATE PROCEDURE sp_desc (
  @tableName  nvarchar(128)
) AS
BEGIN
  DECLARE @dbName       sysname;
  DECLARE @schemaName   sysname;
  DECLARE @objectName   sysname;
  DECLARE @objectID     int;
  DECLARE @tmpTableName varchar(100);
  DECLARE @sqlCmd       nvarchar(4000);

  SELECT @dbName = PARSENAME(@tableName, 3);
  IF @dbName IS NULL SELECT @dbName = DB_NAME();

  SELECT @schemaName = PARSENAME(@tableName, 2);
  IF @schemaName IS NULL SELECT @schemaName = SCHEMA_NAME();

  SELECT @objectName = PARSENAME(@tableName, 1);
  IF @objectName IS NULL
    BEGIN
      PRINT 'Object is missing from your function call!';
      RETURN;
    END;

  SELECT @objectID = OBJECT_ID(@dbName + '.' + @schemaName + '.' + @objectName);
  IF @objectID IS NULL
    BEGIN
      PRINT 'Object [' + @dbName + '].[' + @schemaName + '].[' + @objectName + '] does not exist!';
      RETURN;
    END;

  SELECT @tmpTableName = '#tmp_DESC_' + CAST(@@SPID AS VARCHAR) + REPLACE(REPLACE(REPLACE(REPLACE(CAST(CONVERT(CHAR, GETDATE(), 121) AS VARCHAR), '-', ''), ' ', ''), ':', ''), '.', '');
  --PRINT @tmpTableName;
  SET @sqlCmd = '
    USE ' + @dbName + '
    CREATE TABLE ' + @tmpTableName + ' (
      [NAME]              nvarchar(128) NOT NULL
     ,[TYPE]              varchar(50)
     ,[CHARSET]           varchar(50)
     ,[COLLATION]         varchar(50)
     ,[NULLABLE]          varchar(3)
     ,[DEFAULT]           nvarchar(4000)
     ,[COMMENTS]          nvarchar(3750));

    INSERT INTO ' + @tmpTableName + '
    SELECT
      a.[NAME]
     ,a.[TYPE]
     ,a.[CHARSET]
     ,a.[COLLATION]
     ,a.[NULLABLE]
     ,a.[DEFAULT]
     ,b.[COMMENTS]
    FROM
      (
        SELECT
          COLUMN_NAME                                     AS [NAME]
         ,CASE DATA_TYPE
            WHEN ''char''      THEN DATA_TYPE + ''('' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + '')''
            WHEN ''numeric''   THEN DATA_TYPE + ''('' + CAST(NUMERIC_PRECISION AS VARCHAR) + '', '' + CAST(NUMERIC_SCALE AS VARCHAR) + '')''
            WHEN ''nvarchar''  THEN DATA_TYPE + ''('' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + '')''
            WHEN ''varbinary'' THEN DATA_TYPE + ''('' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + '')''
            WHEN ''varchar''   THEN DATA_TYPE + ''('' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + '')''
            ELSE DATA_TYPE
          END                                             AS [TYPE]
         ,CHARACTER_SET_NAME                              AS [CHARSET]
         ,COLLATION_NAME                                  AS [COLLATION]
         ,IS_NULLABLE                                     AS [NULLABLE]
         ,COLUMN_DEFAULT                                  AS [DEFAULT]
         ,ORDINAL_POSITION
        FROM   
          INFORMATION_SCHEMA.COLUMNS
        WHERE   
          TABLE_NAME = ''' + @objectName + '''
      ) a
      FULL JOIN
      (
         SELECT
           CAST(value AS NVARCHAR)                        AS [COMMENTS]
          ,CAST(objname AS NVARCHAR)                      AS [NAME]
         FROM
           ::fn_listextendedproperty (''MS_Description'', ''user'', ''' + @schemaName + ''', ''table'', ''' + @objectName + ''', ''column'', default)
      ) b
      ON a.NAME COLLATE Hungarian_CI_AS = b.NAME COLLATE Hungarian_CI_AS
    ORDER BY
      a.[ORDINAL_POSITION];

    SELECT * FROM ' + @tmpTableName + ';'

    --PRINT @sqlCmd;

    EXEC sp_executesql @sqlCmd;
    RETURN;
END;
GO

EXEC sys.sp_MS_marksystemobject sp_desc
GO

执行该过程,请输入:

EXEC sp_desc 'YourDB.YourSchema.YourTable';

如果您想获取当前数据库(和模式)对象的描述,只需简单输入以下命令:

EXEC sp_desc 'YourTable';

由于sp_desc是一个系统标记过的过程,因此您甚至可以省略执行命令(不建议这样做):

sp_desc 'YourTable';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接