Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 SQL SERVER 2000 и взрыв мозга! )  [new]
Tketano
Member

Откуда:
Сообщений: 90
Прошу объяснить мне результат выполнения простейшего запроса на SQL SERVER 2000 (голова от поиска решений уже треснула):
declare @tmpT table
	(
		NUMBER int
	)

insert into @tmpT
select -5
union
select 4
union
select 0
union
select 7
union all
select  4

declare @t varchar(8000)
set @t = ''

select @t = @t +
		convert(varchar(10), NUMBER)
from	@tmpT
order by
	ISNULL(NUMBER, -1)

select @t


То, что ожидаю я - "-50447". То, что выдает сервер - "7".
29 апр 14, 15:55    [15953075]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
!)
Guest
Tketano,

Как то так

declare @tmpT table
	(
		NUMBER int
	)

insert into @tmpT
select -5
union
select 4
union
select 0
union
select 7
union all
select  4

declare @t varchar(8000)
set @t = ''

select @t = CASE WHEN  @t='' THEN convert(varchar(10), NUMBER) ELSE @t + convert(varchar(10), NUMBER) END
from	@tmpT

select @t


(5 row(s) affected)
----------------------------------------------------------------------------------------------------------------------------
-50474

(1 row(s) affected)
29 апр 14, 16:04    [15953163]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Tketano,

смотрите план.
Обсуждалось тысячу раз - фича недокументирована, работает не всегда.
Рекомендовали сложные выражения в ORDER BY не применять,
чтобы объегорить оптимизатор, и он выбрал бы "правильный" план с "правильным порядком действий".
Можно сказать поэтому, что это - типичный говнокод.
29 апр 14, 16:06    [15953179]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tаrantino
Member

Откуда:
Сообщений: 3767
!),

вот так кстати работает

select @t = @t +
		convert(varchar(10), [NUMBER])
from	@tmpT
--order by
	--ISNULL([NUMBER], -1
29 апр 14, 16:07    [15953194]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
!)
Guest
Tketano,

Сорри немного ошибся

declare @tmpT table
	(
		NUMBER int
	)

insert into @tmpT
select -5
union
select 4
union
select 0
union
select 7
union all
select  4

declare @t varchar(8000)
set @t = ''

select @t = CASE WHEN  @t='' THEN convert(varchar(10), NUMBER) ELSE @t + convert(varchar(10), NUMBER) END
from	@tmpT
[color=red]
order BY NUMBER ASC
[/color]

select @t

(5 row(s) affected)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-50447

(1 row(s) affected)
29 апр 14, 16:09    [15953224]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tketano
Member

Откуда:
Сообщений: 90
!),

Спасибо! Да, такой вариант вроде работает... Вопрос в том - почему не работает мой?) Не понимаю разницу
29 апр 14, 16:12    [15953246]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tketano
Member

Откуда:
Сообщений: 90
iap,

Т.е. лучше вообще не использовать данный синтаксис а использовать while\курсоры?
29 апр 14, 16:12    [15953250]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Tketano
iap,

Т.е. лучше вообще не использовать данный синтаксис а использовать while\курсоры?
Нууу....
В принципе, конечно, в 2000-м трудно жилось.
На свой страх и риск использовали, конечно.
Курсор надёжнее, конечно. Документирован по крайней мере
29 апр 14, 16:15    [15953268]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
!),

Вы всех запутали.
С
order BY NUMBER ASC
работает независимо от - любой код, а с
order by ISNULL(NUMBER, -1)
не работает ни один представленный код.
29 апр 14, 16:15    [15953274]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tаrantino
Member

Откуда:
Сообщений: 3767
iap,

на 2012 точно так-же работает
29 апр 14, 16:15    [15953275]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
DmitryVT
Member

Откуда: VRN
Сообщений: 192
Вам Выше уже привели объяснение.

/Рекомендовали сложные выражения в ORDER BY не применять,
чтобы объегорить оптимизатор, и он выбрал бы "правильный" план с "правильным порядком действий".

Смотрите план выполнения. Сами все поймете
29 апр 14, 16:16    [15953282]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tketano
Member

Откуда:
Сообщений: 90
Mnior,

Спасибо, что заметили. Не обратил внимание, что он ISNULL выдернул из запроса
29 апр 14, 16:17    [15953290]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Mnior,

я запутал, да?
Скажу тогда определённее: на продуктиве недокументированные конструкции не применять!
29 апр 14, 16:19    [15953305]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tketano
Member

Откуда:
Сообщений: 90
DmitryVT,
если честно, смотрю в план выполнения и до сих пор не понимаю в чем трабл. Стоит хоть написать ISNULL(NUMBER, NUMBER) в ORDER BY и все, запрос сыпется. Не хотелось бы использовать курсор, но видимо придется...
29 апр 14, 16:20    [15953326]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
А всё потому что оптимизатор планов путает порядок операторов.
Поэтому нужно именно так:
DECLARE @Temp TABLE (Value Int)
INSERT	@Temp	SELECT -5
UNION ALL	SELECT 4
UNION ALL	SELECT 0
UNION ALL	SELECT 7
UNION ALL	SELECT 4

DECLARE	@Res	VarChar(8000)
SET	@Res	= ''

SELECT	@Res = @Res + Convert(VarChar,Value)
FROM	(SELECT Top 2147483648 *
FROM	@Temp
ORDER BY IsNull(Value,-1) DESC
) Q

SELECT @Res
По идее в 2000м можно и так:
SELECT	@Res = @Res + Convert(VarChar,Value)
FROM	(SELECT Top 100 PERCENT *
FROM	@Temp
ORDER BY IsNull(Value,-1) DESC
) Q

SELECT @Res
29 апр 14, 16:21    [15953329]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
15953274
Mnior
!),
Вы всех запутали.
iap
Mnior,
я запутал, да?
Прошу прощения что мой ответ господину "!)" шёл именно за вашим.
Он всех путает и ником и кодом.
29 апр 14, 16:27    [15953389]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tketano
Member

Откуда:
Сообщений: 90
Mnior,

Крайне неожиданно... спасибо большое!

Перепишу-ка я на курсоры...) Для уверенности в коде))
29 апр 14, 16:30    [15953414]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tketano
Member

Откуда:
Сообщений: 90
Mnior,

последний вопрос - работа с переменными подобным образом по прежнему относится к разряду недокументированных возможностей? С какой версии сервера я могу не опасаться за конструкцию вида SELECT @Variable = @Variable + ... FROM ...
29 апр 14, 16:42    [15953520]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Tketano
Mnior,

последний вопрос - работа с переменными подобным образом по прежнему относится к разряду недокументированных возможностей? С какой версии сервера я могу не опасаться за конструкцию вида SELECT @Variable = @Variable + ... FROM ...
Я, хоть и не Mnior, могу ответить.
Microsoft игнорирует все до единой просьбы по документированию этой конструкции.
Много-много лет. 99.99% из 100% за то, что никогда не документирует.
29 апр 14, 16:47    [15953575]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tаrantino
Member

Откуда:
Сообщений: 3767
Tketano,

в 2012 работает точно так-же как и в 2000
29 апр 14, 16:50    [15953608]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Tketano
Member

Откуда:
Сообщений: 90
Т.е. лучше использовать исключительно в своих целях, но избегать подобных конструкций в итоговом решении?

На самом деле надо было собрать небольшой xml фрагмент и сохранить его в БД. А по скольку в 2000-ом xml поток инструкции FOR XML никак нельзя обработать на сервере, то возникла мысль использовать данную конструкцию взамен курсоров.
29 апр 14, 16:58    [15953676]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Tketano
в 2000-ом xml поток инструкции FOR XML никак нельзя обработать на сервере
1. Враки это всё. Даже SQLXML появился вместе с 2000м.
2. Вааще на DB сервере должны обрабатываться только DB задачи. Всякие конвертации и всё такое - для этого есть App сервис, клиент.
29 апр 14, 21:30    [15955017]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Mnior
Даже SQLXML появился вместе с 2000м.
15777914 Даунгрейдить строку соединения и типы переменных и всё заработает.
Конечно с табличными переменными @ и временными таблицами # облом. Но ## никто не отменял.
Но это так, пример, скорее к задаче ТС применять не имеет смысла, ХЗ.
29 апр 14, 21:40    [15955060]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
Empirical
Member

Откуда:
Сообщений: 99
Tketano,
и можно без кейсов

select @t = concat(@t,NUMBER)
from	@tmpT
order by NUMBER


Не работает ни в одном из нижеперечисленных вариантов:
1. case when NUMBER is null then -1 else number end
2. coalesce(NUMBER,-1)
3. concat(NUMBER,-1)
4. select @t = concat(@t,t.NUMBER) from (select isnull(number,-1) number from @tmpT) t order by t.NUMBER
5. ;with tab as (select isnull(number,-1) number from @tmpT ) select @t = concat(@t,NUMBER) from tab order by NUMBER
30 апр 14, 01:20    [15955640]     Ответить | Цитировать Сообщить модератору
 Re: SQL SERVER 2000 и взрыв мозга! )  [new]
aleks2
Guest
Empirical
Tketano,
и можно без кейсов

select @t = concat(@t,NUMBER)
from	@tmpT
order by NUMBER


Не работает ни в одном из нижеперечисленных вариантов:
1. case when NUMBER is null then -1 else number end
2. coalesce(NUMBER,-1)
3. concat(NUMBER,-1)
4. select @t = concat(@t,t.NUMBER) from (select isnull(number,-1) number from @tmpT) t order by t.NUMBER
5. ;with tab as (select isnull(number,-1) number from @tmpT ) select @t = concat(@t,NUMBER) from tab order by NUMBER


Открою америку. Все ваши проблемы давно обсосаны и решены.
Надо сложную сортировку или сложно сочиненный запрос?
1. делай временную таблицу али табличную переменную с КЛАСТЕРНЫМ индексом,
2. складывай туды результаты запроса.
3. И фсе.
select @t = concat(@t,NUMBER) from	@tmpT
30 апр 14, 06:32    [15955761]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить