2

有没有一种快速的方法来获取包含列声明所需的 sql 数据类型的字符串,基于数据库中的列/列信息。

例如,我希望返回字符串,例如:

varchar(200)
datetime
numeric(35,5)

SYS.COLUMNS显然,我可以从自己或从中获取生成此信息所需的信息INFORMATION_SCHEMA.COLUMNS并开始处理这些信息,但我想要一种(最好是 MS 提供的)方法来自动将数据类型/最大长度/精​​度/比例信息转换为列声明数据类型。

我猜想如果有一种标准的方法可以做到这一点,它将处理所有可能的数据类型,这将是一个痛苦的尝试手动覆盖。

编辑:对不起 - 似乎我对我想要的东西还不够清楚。

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

编辑:

好的:再来一次:

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

根据列类型声明变量类型

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

4

5 回答 5

3

恐怕我不知道正确的方法,但我已经尝试过INFORMATION_SCHEMA.Columns。这并不漂亮,但确实可以处理数据库默认值、可为空值等。

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'
于 2012-06-18T14:06:58.993 回答
2

这是我的工具箱中的一些东西。请注意,它可以自由转换TEXTVARCHAR(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) 结果

于 2012-06-18T15:15:49.140 回答
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)或上面的查询,您都必须“按摩”返回集以生成正确的数据类型声明。

于 2012-06-18T12:07:29.297 回答
0

第二个结果集sp_help呢?我认为您可以很容易地调整该输出以获得您想要的结果。

于 2012-06-18T12:15:21.770 回答
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
于 2016-08-25T07:05:17.477 回答