2

在 T-SQL 中是否可以使用变量类型转换数据类型?

即虽然这不起作用,因为它需要一个字符串文字,但可以理解要点:

select @DataType = Data_Type
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'emp'
and COLUMN_NAME = 'emp_id'

SELECT
cast(emp_id as @DataType)
FROM emp
4

2 回答 2

7

不,您需要为此使用动态 SQL,例如

DECLARE @sql NVARCHAR(MAX);

SELECT @sql = N'SELECT CAST(emp_id AS ' + Data_Type
 + ') FROM dbo.emp;'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'emp'
AND TABLE_SCHEMA = 'dbo' -- this might be important!
AND COLUMN_NAME = 'emp_id';

PRINT @sql;
-- EXEC sp_executesql @sql;

但是,这对我来说似乎是错误的。为什么不知道列的数据类型?

此外,您将需要一个更复杂的查询,因为您需要考虑精度/比例/最大长度。例如,如果emp_id是 a ,则所有结果都将被截断为一个字符。varchar

最后,我强烈推荐sys.columnsoverINFORMATION_SCHEMA

于 2012-06-18T15:50:22.647 回答
2

我需要做类似的事情,所以我创建了一个函数,以便我可以返回动态 SQL 所需的文字数据类型。我很惊讶我找不到这样的函数已经创建:(或者我不应该感到惊讶,因为我的建议不会通过动态 SQL 进行 CASTING ......但在这一点上,我想不出一个替代方案源表是可变的)

无论如何,这是任何人都需要的功能。请注意,到目前为止,我只包含了我试图 CAST 的表中的数据类型......所以我想任何使用它的人都需要效仿并包括他们需要的数据类型,或者可能包括所有其余的数据类型.

CREATE FUNCTION dbo.GetLiteralDataType( @TableName as VARCHAR(100), @ColumnName as VARCHAR(100) )
    RETURNS VARCHAR(100)
    AS
    BEGIN

        DECLARE @DataType as VARCHAR(100)
        DECLARE @FullDataType as VARCHAR(100)
        DECLARE @MaxLength AS INT
        DECLARE @Precision AS INT
        DECLARE @Scale AS INT


        SET @DataType =(SELECT TOP 1 y.name FROM SYS.TABLES t
        INNER JOIN SYS.COLUMNS c ON t.object_id = c.object_id
        INNER JOIN SYS.TYPES y ON y.system_type_id = c.system_type_id
        WHERE t.name = @TableName AND c.name = @ColumnName)

        SET @MaxLength =(SELECT TOP 1 c.max_length FROM SYS.TABLES t
        INNER JOIN SYS.COLUMNS c ON t.object_id = c.object_id
        INNER JOIN SYS.TYPES y ON y.system_type_id = c.system_type_id
        WHERE t.name = @TableName AND c.name = @ColumnName)

        SET @Precision =(SELECT TOP 1 c.precision FROM SYS.TABLES t
        INNER JOIN SYS.COLUMNS c ON t.object_id = c.object_id
        INNER JOIN SYS.TYPES y ON y.system_type_id = c.system_type_id
        WHERE t.name = @TableName AND c.name = @ColumnName)

        SET @Scale =(SELECT TOP 1 c.scale FROM SYS.TABLES t
        INNER JOIN SYS.COLUMNS c ON t.object_id = c.object_id
        INNER JOIN SYS.TYPES y ON y.system_type_id = c.system_type_id
        WHERE t.name = @TableName AND c.name = @ColumnName)

        IF @DataType ='decimal'
        BEGIN
            SET @FullDataType = 'DECIMAL('+ @Precision + ',' + @Scale + ')'
        END

        IF @DataType ='varchar'
        BEGIN
            SET @FullDataType = 'VARCHAR('+ @MaxLength + ')'
        END

        IF @DataType ='bit'
        BEGIN
            SET @FullDataType = 'BIT'
        END

        IF @DataType ='money'
        BEGIN
            SET @FullDataType = 'MONEY'
        END

        IF @DataType ='date'
        BEGIN
            SET @FullDataType = 'DATE'
        END

        RETURN @FullDataType 
    END
于 2015-07-29T17:11:21.200 回答