代码之家  ›  专栏  ›  技术社区  ›  Tom Tresansky

SQL Server 2005奇怪的varchar行为

  •  2
  • Tom Tresansky  · 技术社区  · 14 年前

    此SQL Server 2005 T-SQL代码:

    DECLARE @Test1 varchar;
    SET @Test1 = 'dog';
    
    DECLARE @Test2 varchar(10);
    SET @Test2 = 'cat';
    
    SELECT @Test1 AS Result1, @Test2 AS Result2;
    

    生产:

    结果1= 结果2=猫

    我也希望

    1. 指派 SET @Test1 = 'dog'; 因为没有失败 足够的空间 @Test1
    2. SELECT 返回结果1列中的“dog”。

    究竟是怎么回事 @测试1 ?有人能解释一下这种行为吗?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Heinzi    14 年前

    让我用SQL Server文档中的一些引号来回答。

    char and varchar

    VARCHAR [(n)]

    当数据定义或变量声明语句中未指定n时,默认长度为1。

    Converting Character Data

    当字符表达式转换为不同大小的字符数据类型时,对新数据类型而言太长的值将被截断。

    因此,您的varchar声明为 varchar(1) 以及你的 SET 语句(从长度为3的字符串文本到 VARCHAR(1) 截断 dog d .

        2
  •  0
  •   KM.    14 年前

    varchar默认为长度1

    DECLARE @Test1 varchar;
    

    尝试此操作,它将使用一个简单的函数,该函数接受一个sql_变量并返回数据类型信息:

    CREATE FUNCTION [dbo].[yourFunction]
    (
         @InputStr      sql_variant   --can not be varchar(max) or nvarchar(max)
    )
    returns
    varchar(8000)
    
    BEGIN
        DECLARE @Value varchar(50)
        --can use SQL_VARIANT_PROPERTY(@InputStr,'BaseType') to determine given datatype
    
        --do whatever you want with @inputStr here
        IF @InputStr IS NULL
        BEGIN
            SET @value= 'was null'
        END
        ELSE IF SQL_VARIANT_PROPERTY(@InputStr,'BaseType')='varchar'
        BEGIN
            --your special code here
            SET @value= 'varchar('+CONVERT(varchar(10),SQL_VARIANT_PROPERTY(@InputStr,'MaxLength '))+') - '+CONVERT(varchar(8000),@InputStr)
        END
        ELSE IF SQL_VARIANT_PROPERTY(@InputStr,'BaseType')='datetime'
        BEGIN
            --your special code here
            SET @value= 'datetime - '+CONVERT(char(23),@InputStr,121)
        END
        ELSE IF SQL_VARIANT_PROPERTY(@InputStr,'BaseType')='nvarchar'
        BEGIN
            --your special code here
            SET @value= 'nvarchar('+CONVERT(varchar(10),CONVERT(int,SQL_VARIANT_PROPERTY(@InputStr,'MaxLength '))/2)+') - '+CONVERT(varchar(8000),@InputStr)
        END
        ELSE
        BEGIN
            --your special code here
            set @value= 'unknown!'
        END
    
        RETURN  @value
    
    END
    GO
    
    DECLARE @Test1 varchar;
    SET @Test1 = 'dog';
    
    DECLARE @Test2 varchar(10);
    SET @Test2 = 'cat';
    
    SELECT @Test1 AS Result1, @Test2 AS Result2;
    
    select [dbo].[yourFunction](@test1)
    

    输出:

    Result1 Result2
    ------- ----------
    d       cat
    
    (1 row(s) affected)
    
    
    -------------------
    varchar(1) - d
    
    (1 row(s) affected)
    

    故事的寓意, 不要懒惰,在所有varchar值上指定一个长度!!!!