获取列创建数据类型以进行声明

时间:2012-06-18 12:02:04

标签: sql sql-server sql-server-2008 tsql

是否有一种快速方法可以根据数据库中的列/列信息获取包含列声明所需的sql数据类型的字符串。

例如,我想要返回字符串,例如:

varchar(200)
datetime
numeric(35,5)

显然,我可以从SYS.COLUMNSINFORMATION_SCHEMA.COLUMNS获取生成此信息所需的信息并开始处理这些信息,但我想要一种(最好是MS提供的)方式来转换数据类型/ maxlength / precision /自动将信息缩放到列声明数据类型中。

我猜想如果有一种标准的方法可以处理所有可能的数据类型,那么尝试手动覆盖会很痛苦。

编辑:对不起 - 我似乎对自己想要的内容不够清楚。

例如,当您在SSMS中为CREATE编写表时,生成的脚本包含我想要的格式的数据类型。有没有办法自动获取这些?

编辑:

好的:再来一次:

我想要的有点像这个问题:

Declaring variable type based on a column type

不同之处在于我不介意动态声明变量,因为我已经在使用动态SQL。

5 个答案:

答案 0 :(得分:3)

我担心我不知道一个正确的方法,但我已经开始做INFORMATION_SCHEMA.Columns方式了。这不是很好,但确实处理数据库默认值,nullables等。

SELECT column_name + ' ' + DATA_TYPE + COALESCE('(' + CASE
                                                        WHEN DATA_TYPE = 'XML' THEN NULL
                                                        WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN 'max'
                                                        ELSE Cast(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(5))
                                                      END + ')', '(' + Cast(NUMERIC_PRECISION AS NVARCHAR(5)) + ',' + Cast(NUMERIC_SCALE AS NVARCHAR(5)) + ')', '') + ' ' + CASE IS_NULLABLE
                                                                                                                                                                              WHEN 'YES' THEN 'NULL'
                                                                                                                                                                              ELSE 'NOT NULL'
                                                                                                                                                                            END + COALESCE(' DEFAULT' + COLUMN_DEFAULT, '')
FROM   INFORMATION_SCHEMA.Columns
WHERE  table_name = 'mytable'

答案 1 :(得分:2)

这是我工具箱中的内容。请注意,可以将TEXT转换为VARCHAR(MAX)。意见可能会有所不同,但我认为这是一个功能,因为我讨厌TEXT类型:)

SELECT REPLACE(REPLACE(REPLACE(CASE ORDINAL_POSITION WHEN 1 THEN '' ELSE ', ' END   +'['+column_name+'] '
    +c.DATA_TYPE
    +ISNULL('('+CAST(c.CHARACTER_MAXIMUM_LENGTH AS VARCHAR(30))+')','')
    +CASE WHEN c.DATA_TYPE IN ('NUMERIC','DECIMAL') THEN
        ISNULL('('+CAST(c.NUMERIC_PRECISION AS VARCHAR(30))+','+CAST(c.NUMERIC_SCALE AS VARCHAR(30))+')','')
        ELSE '' END
    +' ','text(2147483647)','varchar(max)'),'(-1)','(max)')

    -- These last two are optional
    +isnull(CASE WHEN c.IS_NULLABLE='NO' THEN 'NOT ' ELSE NULL END,'')
    +'NULL'
    , 'XML(MAX)','XML')
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE TABLE_NAME='MyTable' and TABLE_SCHEMA='dbo'
ORDER BY ORDINAL_POSITION

编辑:用XML替换XML(MAX)结果

答案 2 :(得分:0)

SELECT
OBJECT_NAME(c.OBJECT_ID) TableName
,c.name AS ColumnName
,t.name AS TypeName
,c.max_length
,c.PRECISION
,c.scale
FROM sys.columns AS c
JOIN sys.types AS t ON c.user_type_id=t.user_type_id
ORDER BY c.OBJECT_ID

我担心无论哪种方式(information_schema.columns)或上面的查询,你都必须“按摩”返回集以生成正确的数据类型声明。

答案 3 :(得分:0)

来自sp_help的第二个结果集怎么样?我认为您可以非常轻松地调整输出以获得您想要的结果。

答案 4 :(得分:0)

这就是我最终的结果(使用SQL Server 2014)

CREATE FUNCTION dbo.GetTypeDeclaration(@schema AS VARCHAR(MAX), @table AS VARCHAR(MAX), @column AS VARCHAR(MAX)) RETURNS VARCHAR(MAX) AS
BEGIN
    DECLARE @type as SYSNAME
    DECLARE @typeDeclaration as VARCHAR(MAX)
    DECLARE @maxLength AS SMALLINT
    DECLARE @precision AS TINYINT
    DECLARE @scale AS TINYINT

    SELECT @type = ty.name, @maxLength = c.max_length, @precision = c.precision, @scale = c.scale
    FROM sys.tables t
    INNER JOIN sys.columns c ON t.object_id = c.object_id
    INNER JOIN sys.types ty ON ty.user_type_id = c.user_type_id
    WHERE t.schema_id = SCHEMA_ID(@schema) AND t.name = @table AND c.name = @column

    IF @maxLength <> -1 AND @type IN ('nchar', 'nvarchar', 'nvarbinary')
    BEGIN
        SET @maxLength = @maxLength / 2
    END

    IF @type IN ('binary', 'char', 'nchar')
    BEGIN
        SET @typeDeclaration = @type + '(' + CAST(@maxLength AS VARCHAR) + ')'
    END
    ELSE IF @type IN ('datetime2', 'datetimeoffset', 'time')
    BEGIN
        SET @typeDeclaration = @type + '(' + CAST(@scale AS VARCHAR) + ')'
    END
    ELSE IF @type IN ('nvarchar', 'nvarbinary', 'varchar', 'varbinary')
    BEGIN
        SET @typeDeclaration = @type + '(' + CASE WHEN @maxLength = -1 THEN 'max' ELSE CAST(@maxLength AS VARCHAR) END + ')'
    END
    ELSE IF @type IN ('decimal', 'numeric')
    BEGIN
        SET @typeDeclaration = @type + '(' + CAST(@precision AS VARCHAR) + ', ' + CAST(@scale AS VARCHAR) + ')'
    END
    ELSE
    BEGIN
        SET @typeDeclaration = @type
    END

    RETURN @typeDeclaration
END