Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Возвращает "0" а нужно " "  [new]
ArtyLyght
Member

Откуда: Пермь
Сообщений: 57
Доброго времени суток!
Столкнулся с тем, что возвращает значение "0", при использовании ISNULL(gorod,' '), когда должен вернуть пустоту, но это видимо связано с типом данных поля. Как написать чтобы вернулось " "?
18 апр 15, 19:45    [17533907]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
Gviber
Member

Откуда:
Сообщений: 124
ISNULL(NULLIF(gorod,0),' ') может так?
18 апр 15, 19:49    [17533922]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
Gviber
Member

Откуда:
Сообщений: 124
ISNULL(NULLIF(gorod,'0'),' ') или так
18 апр 15, 19:51    [17533929]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
Gviber
Member

Откуда:
Сообщений: 124
еще вариант ISNULL(NULLIF(cast(gorod as varchar),'0'),' ')
18 апр 15, 19:56    [17533943]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1753
ArtyLyght,

Воспользуйтесь COALESCE

msdn
ISNULL использует тип данных первого параметра, COALESCE следует правилам выражения CASE и возвращает тип данных значения с самым высоким приоритетом
18 апр 15, 20:14    [17533992]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
ArtyLyght
Member

Откуда: Пермь
Сообщений: 57
Gviber,Спасибо!
Маленько изменил ваш вариант, ISNULL(cast(god_remont as varchar),' ')
Тут явно напрашивалось изменения типа данных
18 апр 15, 20:18    [17534005]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1753
ArtyLyght
Gviber,Спасибо!
Маленько изменил ваш вариант, ISNULL(cast(god_remont as varchar),' ')
Тут явно напрашивалось изменения типа данных

Я для вас написал что надо использовать COALESCE тогда не нужно ничего приводить...
18 апр 15, 20:21    [17534011]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
ArtyLyght
Member

Откуда: Пермь
Сообщений: 57
X-Cite, возможно я неправильно применяю его но у меня в итоге все равно возвращается 0 при использовании COALESCE
18 апр 15, 20:25    [17534022]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
Gviber
Member

Откуда:
Сообщений: 124
Интересно COALESCE работает
DECLARE @x AS int = null, @y AS VARCHAR(10) = 'test', @z as datetime = null
SELECT COALESCE(@x, @y, @z)  

--Ошибка преобразования даты или времени из символьной строки.

Похоже работает в зависимости от приоритетов т.к. по приоритетам: datetime > int > VARCHAR

Но если приоритеты одинаковые вернет уже в зависимости от места:
DECLARE @x AS NVARCHAR(3) = NULL, @y AS VARCHAR(10) = '1234567890';
SELECT COALESCE(@x, @y)

--будет '1234567890'
18 апр 15, 20:54    [17534077]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
Gviber
Member

Откуда:
Сообщений: 124
Хотя с приоритетами тоже не ясно т.к. по приоритетам nvarchar > varchar, но не равен.
18 апр 15, 21:13    [17534137]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
Gviber
Member

Откуда:
Сообщений: 124
DECLARE @x AS NVARCHAR(1) = NULL, @y AS VARCHAR(10) = '1234567890';
SELECT DATALENGTH(COALESCE(@x, @y)) --20
	   ,COALESCE(@x, @y)			--1234567890
	   ,DATALENGTH(@y)				--10

Это сильно =). Получается от все же взял NVARCHAR но ограничение в 10 символов скопировал от VARCHAR
18 апр 15, 21:20    [17534153]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
o-o
Guest
Gviber
DECLARE @x AS NVARCHAR(1) = NULL, @y AS VARCHAR(10) = '1234567890';
SELECT DATALENGTH(COALESCE(@x, @y)) --20
	   ,COALESCE(@x, @y)			--1234567890
	   ,DATALENGTH(@y)				--10

Это сильно =). Получается от все же взял NVARCHAR но ограничение в 10 символов скопировал от VARCHAR

да не скопировал он никакое ограничение, вы совсем документацию не читаете, даже если ее другие цитируют?
X-Cite
msdn
COALESCE следует правилам выражения CASE и возвращает тип данных значения с самым высоким приоритетом

результирующим типом будет NVARCHAR, т.к. у него из перечисленных наивысший приоритет.
длина -- это конкретная длина результата, а никакое не ограничение,
ну пререправьте VARCHAR(10) на VARCHAR(100), все равно DATALENGTH(COALESCE(@x, @y)) = 20,
ведь это длина в байтах результата '1234567890', приведенного к NVARCHAR.
и вообще вот так все отлично видно:
DECLARE @x AS NVARCHAR(1) = NULL, @y AS VARCHAR(100) = '1234567890';
SELECT DATALENGTH(COALESCE(@x, @y)) --20
	   ,COALESCE(@x, @y)			--1234567890
	   ,DATALENGTH(@y)				--10
	   ,SQL_VARIANT_PROPERTY(COALESCE(@x, @y), 'basetype') as result_type
	   ,SQL_VARIANT_PROPERTY(COALESCE(@x, @y), 'MaxLength') as max_length
---
(No column name)	(No column name)	(No column name)	result_type	max_length
20	                 1234567890	         10	                nvarchar	200
18 апр 15, 23:06    [17534436]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
Gviber
Member

Откуда:
Сообщений: 124
Ну я как раз имел ввиду, что varchar(100) превращается в nvarchar(100), при этом nvarchar(100) нигде явно не указан.

DATALENGTH(COALESCE(@x, @y)) был нужен, чтобы показать, что размер строки увеличился в два раза, а следствие строка стала unicode. Не знал про SQL_VARIANT_PROPERTY - спасибо =)
19 апр 15, 00:56    [17534756]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
o-o
Guest
Gviber
Ну я как раз имел ввиду, что varchar(100) превращается в nvarchar(100), при этом nvarchar(100) нигде явно не указан.

по-моему, мы все же про разное.
т.е. я не понимаю, что вас удивляет.
тип результата COALESCE -- это наивысший по приоритету тип.
в вашем примере им оказался nvarchar, в моем новом примере это datetime2(1):
DECLARE @x AS NVARCHAR(200) = NULL, @y AS VARCHAR(10) = '67890123', @z datetime2(1) = '1980';
SELECT DATALENGTH(COALESCE(@x, @y, @z)) --6
	   ,COALESCE(@x, @y, @z)			--6789-01-23 00:00:00.0000000
	   ,DATALENGTH(@y)				--8
	   ,SQL_VARIANT_PROPERTY(COALESCE(@x, @y, @z), 'basetype') as result_type --datetime2
	   ,SQL_VARIANT_PROPERTY(COALESCE(@x, @y, @z), 'MaxLength') as max_length --6

(No column name) (No column name) (No column name) result_type max_length
6 6789-01-23 00:00:00.0 8 datetime2 6


размер результата -- это размер первого не-NULL аргумента,
приведенного к результирующему типу.
у вас результирующим типом стал nvarchar, длина результата 10 символов,
привели к nvarchar, получили 20 байт.

т.е. вообще-то обычно хватает определить наивысший по приоритету тип,
и его (фиксированный) размер и будет размером результата,
но именно в случае varchar/nvarchar тип не фиксированной длины,
поэтому размер результата определился, исходя из размера конкретного аргумента,
а не из размера результирующего типа.
но при этом макс. размер результата высчитался пересчетом макс. размера первого не- аргумента.

надеюсь, не очень запутанноe объяснение Картинка с другого сайта.
19 апр 15, 22:19    [17536907]     Ответить | Цитировать Сообщить модератору
 Re: Возвращает "0" а нужно " "  [new]
o-o
Guest
o-o
но при этом макс. размер результата высчитался пересчетом макс. размера первого не- аргумента.

--> первого не-NULL аргумента
19 апр 15, 22:23    [17536915]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить