【问题标题】:SQL get table columns with type nameSQL 获取具有类型名称的表列
【发布时间】:2015-07-17 02:13:59
【问题描述】:

我已经成功地从下面的查询中获取了表和列的信息。

是否有任何方便的方法来获取带有 nvarchar(20)numeric(14,2)varchar(max) 等描述的类型名称,而不是大量的 CASE 语句?

SELECT 
    o.name AS TableName,
    c.name AS ColumnName,
    t.name + 
    CASE 
        WHEN t.name LIKE '%char' THEN '(' + 
            CASE 
                WHEN c.max_length = -1 THEN 'max' 
                ELSE CONVERT(varchar(10), c.max_length / CASE WHEN t.name LIKE 'n%' THEN 2 ELSE 1 END) 
            END + ')'
        WHEN t.name IN ('numeric', 'decimal') THEN '(' + CONVERT(varchar(4), c.precision) + ',' + CONVERT(varchar(4), c.scale) + ')'
        -- WHEN .... many other types
        ELSE ''
    END AS TypeName
FROM 
    sys.objects o 
    INNER JOIN sys.columns c ON o.object_id = c.object_id
    INNER JOIN sys.types t ON t.system_type_id = c.system_type_id AND t.user_type_id = c.user_type_id
WHERE
    o.is_ms_shipped = 0
ORDER BY
    o.name,
    c.column_id

编辑

sp_help 和信息架构返回的名称不是 nvarchar(20)numeric(14,2)varchar(max)

【问题讨论】:

  • 我很确定你被 case 表达式卡住了,因为据我所知,没有系统视图可以以你想要的格式显示信息。
  • @jpw 是的,你是对的,知道真相很难过

标签: sql sql-server-2008


【解决方案1】:

我使用这个视图来记录数据库......你可以使用它并使用 data_type 和 Length/Precision

/****** Object:  View [dbo].[vw_DataDictionary]    Script Date: 17/07/2015 10:24:04 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER VIEW [dbo].[vw_DataDictionary]
AS
SELECT     TOP (100) PERCENT tb.name AS Table_Name, CAST(ept.value AS nvarchar(200)) AS Table_Description, CAST(c.name AS nvarchar(200)) AS Column_Name, 
                      CAST(ep.value AS nvarchar(200)) AS column_Description, t.name AS data_type, c.is_nullable AS Is_Null, object_definition(c.default_object_id) AS default_text, 
                      c.max_length AS Length, c.precision AS numeric_precision, c.scale AS numeric_scale, c.column_id
FROM         sys.columns AS c LEFT OUTER JOIN
                      sys.tables AS tb ON tb.object_id = c.object_id LEFT OUTER JOIN
                      sys.types AS t ON c.system_type_id = t.system_type_id AND c.user_type_id = t.user_type_id LEFT OUTER JOIN
                      sys.extended_properties AS ept ON ept.major_id = tb.object_id AND ept.minor_id = 0 AND ept.name = 'MS_Description' LEFT OUTER JOIN
                      sys.extended_properties AS ep ON ep.major_id = c.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description'
WHERE     (tb.type = 'U') AND (tb.name <> 'sysdiagrams')
ORDER BY Table_Name, c.column_id

GO

【讨论】:

  • 谢谢,不过好像还是需要像问题中的方式那样格式化类型
【解决方案2】:

对于 SQL Server 2008 R2,我已通过CASE 声明类型如下:

SQL Fiddle

SELECT 
    DB_NAME() AS DatabaseName, 
    SCHEMA_NAME(o.schema_id) AS SchemaName, 
    o.name AS ObjectName, 
    c.name AS ColumnName, 
    RTRIM(o.type) AS ObjectType, 
    t.name AS TypeName,
    c.max_length AS Length,

    -- The logic is implemented in this column
    t.name + 
    CASE 
        -- (max) for char type / binary only
        WHEN (t.name LIKE '%char%' OR t.name LIKE '%binary') AND c.max_length = -1 THEN '(max)'
        -- (n) where n = length / 2 for nchar and nvarchar
        WHEN t.name LIKE '%char%' AND LEFT(t.name, 1) = 'n' THEN '(' + CONVERT(varchar, c.max_length / 2) + ')' 
        -- (n) where n = length
        WHEN t.name LIKE '%char%' OR t.name LIKE '%binary' THEN '(' + CONVERT(varchar, c.max_length) + ')' 
        -- (p,s) where p = precision, s = scale
        WHEN t.name IN ('numeric', 'decimal') THEN '(' + CONVERT(varchar, c.precision) + ',' + CONVERT(varchar, c.scale) + ')'
        -- (s) where s = scale
        WHEN t.name IN ('time', 'datetime2', 'datetimeoffset') THEN '(' + CONVERT(varchar, c.scale) + ')'
        ELSE '' 
    END AS Type
FROM 
    sys.objects o 
    inner join sys.columns c on o.object_id = c.object_id
    inner join sys.types t on c.system_type_id = t.system_type_id and c.user_type_id = t.user_type_id
WHERE 1 = 1
    AND o.is_ms_shipped = 1

【讨论】:

    【解决方案3】:

    这应该对你有帮助,来自here

    DECLARE @tblname VARCHAR(300)
    
    SET @tblname = 'tblname'
    
    SELECT o.list AS ColumnsDescription
    FROM sysobjects so
    CROSS APPLY (
        SELECT '  [' + column_name + '] ' + data_type + CASE data_type
                WHEN 'sql_variant'
                    THEN ''
                WHEN 'text'
                    THEN ''
                WHEN 'ntext'
                    THEN ''
                WHEN 'xml'
                    THEN ''
                WHEN 'decimal'
                    THEN '(' + cast(numeric_precision AS VARCHAR) + ', ' + cast(numeric_scale AS VARCHAR) + ')'
                ELSE coalesce('(' + CASE 
                            WHEN character_maximum_length = - 1
                                THEN 'MAX'
                            ELSE cast(character_maximum_length AS VARCHAR)
                            END + ')', '')
                END + ' ' + CASE 
                WHEN EXISTS (
                        SELECT id
                        FROM syscolumns
                        WHERE object_name(id) = so.NAME
                            AND NAME = column_name
                            AND columnproperty(id, NAME, 'IsIdentity') = 1
                        )
                    THEN 'IDENTITY(' + cast(ident_seed(so.NAME) AS VARCHAR) + ',' + cast(ident_incr(so.NAME) AS VARCHAR) + ')'
                ELSE ''
                END + ' ' + (
                CASE 
                    WHEN IS_NULLABLE = 'No'
                        THEN 'NOT '
                    ELSE ''
                    END
                ) + 'NULL ' + CASE 
                WHEN information_schema.columns.COLUMN_DEFAULT IS NOT NULL
                    THEN 'DEFAULT ' + information_schema.columns.COLUMN_DEFAULT
                ELSE ''
                END + ', '
        FROM information_schema.columns
        WHERE table_name = so.NAME
        ORDER BY ordinal_position
        FOR XML PATH('')
        ) o(list)
    LEFT JOIN information_schema.table_constraints tc ON tc.Table_name = so.NAME
        AND tc.Constraint_Type = 'PRIMARY KEY'
    CROSS APPLY (
        SELECT '[' + Column_Name + '], '
        FROM information_schema.key_column_usage kcu
        WHERE kcu.Constraint_Name = tc.Constraint_Name
        ORDER BY ORDINAL_POSITION
        FOR XML PATH('')
        ) j(list)
    WHERE xtype = 'U'
        AND NAME = @tblname
    

    您可以根据需要解析结果。

    【讨论】:

      【解决方案4】:
      SELECT 
              COLUMN_NAME, 
              CASE 
              WHEN DATA_TYPE ='decimal' THEN DATA_TYPE+ '('+cast (NUMERIC_PRECISION as Varchar)+ ','+cast (NUMERIC_SCALE as Varchar)+ ')'
              WHEN CHARACTER_MAXIMUM_LENGTH is null THEN DATA_TYPE + cast ('' as Varchar) 
              ELSE DATA_TYPE + '('+ cast (CHARACTER_MAXIMUM_LENGTH as Varchar)+')' END AS QuantityText
          
          FROM 
              INFORMATION_SCHEMA.COLUMNS
          WHERE 
              TABLE_NAME = 'table_name' and TABLE_SCHEMA = 'dbo'
              order by COLUMN_NAME
      

      【讨论】:

        猜你喜欢
        • 2013-09-20
        • 1970-01-01
        • 2019-05-29
        • 2021-07-12
        • 2012-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多