是否有一种快速方法可以根据数据库中的列/列信息获取包含列声明所需的sql数据类型的字符串。
例如,我想要返回字符串,例如:
varchar(200)
datetime
numeric(35,5)
显然,我可以从SYS.COLUMNS
或INFORMATION_SCHEMA.COLUMNS
获取生成此信息所需的信息并开始处理这些信息,但我想要一种(最好是MS提供的)方式来转换数据类型/ maxlength / precision /自动将信息缩放到列声明数据类型中。
我猜想如果有一种标准的方法可以处理所有可能的数据类型,那么尝试手动覆盖会很痛苦。
编辑:对不起 - 我似乎对自己想要的内容不够清楚。
例如,当您在SSMS中为CREATE
编写表时,生成的脚本包含我想要的格式的数据类型。有没有办法自动获取这些?
编辑:
好的:再来一次:
我想要的有点像这个问题:
Declaring variable type based on a column type
不同之处在于我不介意动态声明变量,因为我已经在使用动态SQL。
答案 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