SQL Server 2005 странное поведение varchar - PullRequest
2 голосов
/ 20 апреля 2010

Этот код 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 = d Результат2 = кошка

Я бы ожидал либо

  1. Назначение SET @Test1 = 'dog'; не выполнено, потому что нет достаточно места в @Test1
  2. Или SELECT для возврата «собаки» в столбце Result1.

Что случилось с @Test1? Может ли кто-нибудь объяснить это поведение?

Ответы [ 2 ]

2 голосов
/ 20 апреля 2010

Позвольте мне ответить некоторыми цитатами из документации по SQL Server.

чар и варчар

VARCHAR [(п)]

...

Если n не указано в определении данных или в объявлении переменной, длина по умолчанию равна 1.

Преобразование символьных данных

Когда символьные выражения преобразуются в символьный тип данных другого размера, значения, которые являются слишком длинными для нового типа данных, усекаются.

Итак, ваш varchar объявлен как varchar(1), и неявное преобразование в вашем операторе SET (из строкового литерала длины 3 в varchar(1)) усекает dog до d.

0 голосов
/ 20 апреля 2010

VARCHAR по умолчанию имеет длину один

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 !!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...