SQL Server / TSQL - 获取列文字数据类型(带长度)

时间:2017-12-14 02:00:39

标签: sql-server tsql

我需要完成一个像默认设计表(右键单击表和印刷设计)的表:

Data Type With length

通过以下查询,我可以获得为表中每个字段指定的长度:

SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @tablename
ORDER BY ORDINAL_POSITION;

但是想象一下像text这样的数据类型,其中CHARACTER_MAXIMUM_LENGTH不为空(2147483647),但它的值应该只是数据类型列中的“text”。

任何想法如何才能使这种行为正确?其他每个问题都不需要“文字”数据类型。

编辑:有些人无法理解我的假装,我会尽力解释。我想从列中获取完整数据类型,我甚至给出了预期的输出(数据类型列)。想象一下,我有一个像int这样的列的表 ,text,varchar,datetime2。我想要这样的数据类型:intvarchar(120)textdatetime2(7)。此结果是设计列中的数据类型列。

1 个答案:

答案 0 :(得分:3)

下面是一个示例T-SQL脚本,它将返回完整的列定义。如果您不想要完整的列定义,则可以删除不需要的属性。

DECLARE @SourceTableName nvarchar(261) = N'Person.Address';
SELECT 
    CASE 
        WHEN c.is_computed = 1 
            THEN QUOTENAME(c.name) + N' AS (' + cc.definition + N')'
        ELSE
            QUOTENAME(c.name) 
            + ' ' + TYPE_NAME(c.user_type_id)
            + CASE 
                --types without length, precision, or scale specifiecation
                WHEN TYPE_NAME(c.user_type_id) IN (N'int',N'bigint',N'smallint',N'tinyint',N'money',N'smallmoney',N'real',N'datetime',N'smalldatetime',N'bit',N'image',N'text',N'uniqueidentifier',N'date',N'ntext',N'sql_variant',N'hierarchyid','geography',N'timestamp',N'xml') 
                    THEN N''
                --types with precision and scale specification
                WHEN TYPE_NAME(c.user_type_id) in (N'decimal',N'numeric') 
                    THEN N'(' + CAST(c.precision AS varchar(5)) + N',' + CAST(c.scale AS varchar(5)) + N')'
                --types with scale specification only
                WHEN TYPE_NAME(c.user_type_id) in (N'time',N'datetime2',N'datetimeoffset') 
                    THEN N'(' + CAST(c.scale AS varchar(5)) + N')'
                --float default precision is 53 - add precision when column has a different precision value
                WHEN TYPE_NAME(c.user_type_id) in (N'float')
                    THEN CASE WHEN c.precision = 53 THEN N'' ELSE N'(' + CAST(c.precision AS varchar(5)) + N')' END
                --types with length specifiecation
                ELSE N'(' + CASE c.max_length WHEN -1 THEN N'MAX' ELSE CAST(c.max_length AS nvarchar(20)) END + N')'
        END
        + CASE WHEN c.is_filestream = 1 THEN N' FILESTREAM' ELSE '' END
        + COALESCE(N' COLLATE ' + c.collation_name, N'')
        + CASE WHEN c.is_sparse = 1 THEN N' SPARSE' ELSE N'' END
        + CASE WHEN c.is_identity = 1 THEN N' IDENTITY(' + CAST(IDENT_SEED(@SourceTableName) AS varchar(20)) + ',' + CAST(IDENT_INCR(@SourceTableName) AS varchar(20)) + ')' ELSE '' END
        + CASE WHEN c.is_rowguidcol = 1 THEN N' ROWGUIDCOL' ELSE '' END
        + CASE WHEN c.is_nullable = 1 THEN N' NULL' ELSE N' NOT NULL' END
    END
FROM sys.columns AS c (NOLOCK) 
LEFT JOIN sys.computed_columns AS cc (NOLOCK) ON
    cc.object_id = c.object_id
    AND cc.column_id = c.column_id
WHERE
    c.object_id = OBJECT_ID(@SourceTableName)
ORDER BY c.column_id;

结果,来自AdventureWorks数据库Person.Address表:

[AddressID] int IDENTITY(1,1) NOT NULL
[AddressLine1] nvarchar(120) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
[AddressLine2] nvarchar(120) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
[City] nvarchar(60) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
[StateProvinceID] int NOT NULL
[PostalCode] nvarchar(30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
[SpatialLocation] geography NULL
[rowguid] uniqueidentifier ROWGUIDCOL NOT NULL
[ModifiedDate] datetime NOT NULL