SQL Server 2005奇怪的varchar行为

时间:2010-04-20 14:40:28

标签: sql-server sql-server-2005 tsql

此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;

产生

Result1 = d Result2 = cat

我希望

  1. 分配SET @Test1 = 'dog';失败,因为没有 @Test1
  2. 中有足够的空间
  3. 或者SELECT在Result1列中返回'dog'。
  4. @Test1有什么用?有人可以解释一下这种行为吗?

2 个答案:

答案 0 :(得分:2)

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

char and varchar

  

<强> VARCHAR [(N)]

     

...

     

如果未在数据定义或变量声明语句中指定n,则默认长度为1.

Converting Character Data

  

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

因此,您的varchar被声明为varchar(1),并且SET语句中的隐式转换(从长度为3的字符串文字到varchar(1))会截断{{1} } dog

答案 1 :(得分:0)

varchar默认为长度为1

DECLARE @Test1 varchar;

试试这个,它将使用一个带有sql_variant的简单函数并返回数据类型信息:

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值的长度!!!