Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Неожиданное поведение REPLACE  [new]
burunduk
Guest
select cast( replace( cast( 0x000000 as varchar(3) ), char(0x00), char(0x01) ) as varbinary(160) )

На одних серверах результат 0x010101
На других 0x01
6 май 04, 16:15    [666048]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
Никто не сталкивался?
6 май 04, 16:43    [666173]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
Все, я фигею. Не могу понять ЧТО влияет на поведение replace. Сервера абсолютно идентичны.
6 май 04, 16:55    [666220]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Не понимаю смысла этого преобразования - cast( 0x000000 as varchar(3) ). Насколько я понимаю, вы в любом случае получаете пустую строку - хоть длину 3 поставить, хоть сколько. Ну и что вы в ней потом хотите заменять?
6 май 04, 16:58    [666234]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Toking
Member

Откуда: Ковров>>Королев
Сообщений: 234
Привет!

я не совсем понял зачем это нужно?

нет ничего невозможного ... :-)
6 май 04, 16:58    [666236]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
Да это я уже просто все варианты пробовал. Действительно, преобразование к varchar тут не нужно
Но так тоже не работает:
select cast( replace( 0x000000, 0x00, 0x40 ) as varbinary(3) )
6 май 04, 17:00    [666241]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
А нужно это только лишь для того, чтобы заменить 0x00 на 0x01 и больше ничего :)
6 май 04, 17:01    [666253]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
А вот так работает:
select cast( replace( ( cast( 0x000000 as varchar(3) ) collate SQL_Latin1_General_CP1251_CI_AS )
                    , 0x00
                    , 0x40
                    )
             as varbinary(3)
           )

Кто может пояснить причем тут collation???
6 май 04, 17:16    [666287]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
дело не в коллатионе...
с коллатионом тоже самое :)
посмотрите луче ето ю)
select len(0x000000)
select len(cast(0x000000 as varchar(3)))
select len(0x00)
select len(cast(0x00 as varchar(3)))




для спящего время бодрствования равносильно сну
6 май 04, 17:26    [666317]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
А причем здесь длина? Ну понятно, что datalength( cast( 0x00 as varchar(255) ) будет равна 1. И что дальше?
6 май 04, 17:31    [666331]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Maternus
Member

Откуда: Frankfurt am Main
Сообщений: 114
REPLACE - относиться к строковым функциям, и в данном случае ведет себя вполне адекватно :). Ваше преобразование
cast( 0x000000 as varchar(3))
возвращает пустую строку. Предлагаю испольвовать преобразование в тип Integer и работать с ним.


BOL Note: Because Unicode data always uses an even number of bytes, use caution when converting binary or varbinary to or from Unicode supported data types. For example, this conversion does not return a hexadecimal value of 41, but of 4100: SELECT CAST(CAST(0x41 AS nvarchar) AS varbinary)
6 май 04, 17:33    [666334]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
а то, что вы в строку с длинной 3 делаете реплейс символа длинной 1... он вам в трех и заменяет? так что это правильно.

select cast( replace( cast( 0x000000 as varchar(1) ), char(0x00), char(0x01) ) as varbinary(160) )

так низя?



для спящего время бодрствования равносильно сну
6 май 04, 17:34    [666338]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
2Maternus
ну уж... не пустую строку!!
а строку с длинной в три символа и ети символы char(0) :)
а ето немного разные весчи...


для спящего время бодрствования равносильно сну
6 май 04, 17:35    [666343]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Maternus
Member

Откуда: Frankfurt am Main
Сообщений: 114
..Unicode - ключевое слово в моем посте..
6 май 04, 17:37    [666354]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
2 Maternus: действительно строка никак не пустая, а содержит 3 символа с кодом 0

2 Алексей: ты немного не понял вопроса. Смотри результаты запросов:
select cast( replace( ( cast( 0x000000 as varchar(3) ) collate Cyrillic_General_BIN )
                    , 0x00
                    , 0x40
                    )
             as varbinary(3)
           )
select cast( replace( ( cast( 0x000000 as varchar(3) ) collate Cyrillic_General_CI_AS )
                    , 0x00
                    , 0x40
                    )
             as varbinary(3)
           )
Может кто-нибудь пояснить?
6 май 04, 17:40    [666360]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
2 Maternus: а причем здесь юникод? Я юникод не трогаю
6 май 04, 17:41    [666369]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Glory
Member

Откуда:
Сообщений: 104764
2burunduk
Я вам еще более интересный случай покажу
select cast( replace( ( cast( 0x100010 as varchar(3) ))
                    , 0x10
                    , 0x40
                    )
             as varbinary(3)
           )
По всей видимости символ 0x00 просто игнорируется replace-ом
6 май 04, 17:46    [666381]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
Пипец короче, поведение не предсказуемо :) И при некоторых collation все работает как надо. Понять бы чем эти collation отличаются.
6 май 04, 17:55    [666403]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Glory
Member

Откуда:
Сообщений: 104764
Понять бы чем эти collation отличаются.
Я так понимаю что BIN и не BIN
6 май 04, 18:00    [666417]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
С SQL_Latin1_General_CP1251_CI_AS тоже работает, хотя это вроде не BIN
6 май 04, 18:02    [666421]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Maternus
Member

Откуда: Frankfurt am Main
Сообщений: 114
2 burunduk: Unicode "трогает" CAST ;)
Попробуйте кастить в NVARCHAR. Тогда работать будет но всеравно неправильно. А что Int не обойтись ??
6 май 04, 18:16    [666454]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
burunduk
Guest
А как cast в этом случае затрагивает юникод? Что-то я не допонимаю видимо. Ну неправильно и так работает, надо правильно :) Int не устраивает
6 май 04, 18:22    [666462]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Может, так?
select replace( master.dbo.fn_varbintohexstr( 0x000000 ), '00', '01' )
Только еще обратно надо перегнать в binary, а вот с этим проблемы. Надо писать функцию, обратную fn_varbintohexstr. CAST не прокатит.
6 май 04, 18:50    [666509]     Ответить | Цитировать Сообщить модератору
 Re: Неожиданное поведение REPLACE  [new]
Maternus
Member

Откуда: Frankfurt am Main
Сообщений: 114
Ну заметьте Вы разницу между
select cast( replace( cast( 0x000000 as varchar(3) ), char(0x00), char(0x01) ) as varbinary(160) )
select cast( replace( cast( 0x000000 as nvarchar(3) ), char(0x00), char(0x01) ) as varbinary(160) )

те cast в non-Unicode и Unicode тип

Затем следует разочарование в виде предупреждения из BOL о проблемах конвертации типов binary и varbinary (см мой первый пост).

Правда можно попробовать кастить в юникодовскую строку а затем в бинари фиксированной длины . может быть это Вас устроит ?
select cast( replace( cast( 0x000000 as nvarchar(3)), char(0x00), char(0x01)) as binary(160) )
6 май 04, 18:53    [666513]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить