Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Чемодан
Guest
Всем доброго дня.
Несложный запрос, состоящий из четырёх вложенных однотипных подзапросов, приводит к сообщению
Msg 8632, Level 17, State 2, Line 8
Internal error: An expression services limit has been reached. Please look for potentially complex expressions in your query, and try to simplify them.


Что посоветуете ? (запрос должен быть гораздо большей вложенности, чем 4 (порядка 45 уровней)).

Вот скрипт:

if (not object_id('tempdb..##numPairs') is null)
drop table ##numPairs
create table ##numPairs(n1 int not null, n2 int not null)

insert into ##numPairs(n1,n2)
select 1134903170,1836311903

select a,b
      ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
      ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
from(
  select a,b
        ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
        ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
  from(
    select a,b
          ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
          ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
    from(
      select a,b
            ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
            ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
      from(
        select a,b,ax=case when a>=b then a%b else a end,bx=case when a<b then b%a else b end
        from (select a=n1,b=n2 from ##numPairs )c
      )n
    )n
  )n
)n 

Кстати, если закомментировать самый внешний запрос, и оставить "тройную" вложенность, то работает Ок:

  select a,b
        ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
        ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
  from(
    select a,b
          ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
          ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
    from(
      select a,b
            ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
            ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
      from(
        select a,b,ax=case when a>=b then a%b else a end,bx=case when a<b then b%a else b end
        from (select a=n1,b=n2 from ##numPairs )c
      )n
    )n
  )n
Выдаёт:
abaxbx
11349031701836311903165580141267914296
19 май 09, 18:26    [7200289]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36823
Напрмер, гонять отдельными запросами с апдейтом временной таблички.
19 май 09, 18:29    [7200303]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Чемодан
Guest
Гавриленко Сергей Алексеевич
гонять отдельными запросами с апдейтом временной таблички.
Увы, не могу. Тут требуется одним запросом всё сбацать - поспорил с товарищами, что так можно сделать :-)
ЗЫ. Этот запрос - попытка реализовать алгоритм Eвклидa для поиска НОД. Приведенный тест - на двух числах Фибоначчи, самый "неприятный" вариант чисел для этого алгоритма.
19 май 09, 18:35    [7200344]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36823
Чемодан
Гавриленко Сергей Алексеевич
гонять отдельными запросами с апдейтом временной таблички.
Увы, не могу. Тут требуется одним запросом всё сбацать - поспорил с товарищами, что так можно сделать :-)
ЗЫ. Этот запрос - попытка реализовать алгоритм Eвклидa для поиска НОД. Приведенный тест - на двух числах Фибоначчи, самый "неприятный" вариант чисел для этого алгоритма.
А cte - тоже один запрос?
19 май 09, 18:40    [7200368]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Чемодан
Guest
Гавриленко Сергей Алексеевич
А cte - тоже один запрос?

При юзании СТЕ получилась "веселуха": запрос на 8-ой СТЕшке ушёл в себя. Даже не сам запрос, а его парсинг (впрочем, это лишь догадка). После минутного ожидания решил грохнуть его - так еще три минуты шло "Cancelling query" в статус-строке студии. Пришлось грохать студию, которая, как было видно в таск манагере, кушала к этому времени уже около 25Мб :-)
Вот "оно", проверьте у себя, плз:
if (not object_id('tempdb..##numPairs') is null)
drop table ##numPairs
create table ##numPairs(n1 int not null, n2 int not null)

insert into ##numPairs(n1,n2)
select 1134903170,1836311903
go

with n01 as
(
        select a,b,ax=case when a>=b then a%b else a end,bx=case when a<b then b%a else b end
        from (select a=n1,b=n2 from ##numPairs )c
)
--select * from n01
,n02 as
(
      select a,b
            ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
            ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from n01
)
--select * from n02
,n03 as
(
      select a,b
            ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
            ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from n02
)
--select * from n03
,n04 as
(
      select a,b
            ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
            ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from n03
)
--select * from n04
,n05 as
(
      select a,b
            ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
            ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from n04
)
--select * from n05

,n06 as
(
      select a,b
            ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
            ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from n05
)
,n07 as
(
      select a,b
            ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
            ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from n06
)
,n08 as
(
      select a,b
            ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
            ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from n07
)
select * from n08


ЗЫ. select @@version = Microsoft SQL Server 2005 - 9.00.3077.00 (Intel X86) Dec 17 2008 15:19:45 Copyright (c) 1988-2005 Microsoft Corporation Express Edition on Windows NT 5.0 (Build 2195: Service Pack 4)
19 май 09, 18:57    [7200444]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
Чемодан
Увы, не могу. Тут требуется одним запросом всё сбацать - поспорил с товарищами, что так можно сделать :-)
ЗЫ. Этот запрос - попытка реализовать алгоритм Eвклидa для поиска НОД. Приведенный тест - на двух числах Фибоначчи, самый "неприятный" вариант чисел для этого алгоритма.


Но ведь в общем случае не известно сколько будет таких вот запросов. Их количество зависит от чисел.
?
А Вы просто хотите в лоб написать подзапрос 45 раз? А в чем фишка?
Или для всех Фибоначчи будет всегда 45? :)
20 май 09, 04:54    [7201472]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
Чемодан
При юзании СТЕ получилась "веселуха"


Какой-то у Вас СТЕ несимпотичный получился

create table #numPairs(a int not null, b int not null)

insert into #numPairs(b, a)
select 1134903170,1836311903;

WITH NOD(a, b, ax, bx, [Level])
AS
(
    SELECT 	a, b,
			CASE WHEN a>=b THEN a-b ELSE a END ax,
			CASE WHEN a<b THEN b-a ELSE b END bx,
		0 AS [Level]
    FROM #numPairs

    UNION ALL
    SELECT a, b,
			CASE WHEN ax>=bx THEN ax-bx ELSE ax END ax,
			CASE WHEN ax<bx THEN bx-ax ELSE bx END bx,
        [Level] + 1
    FROM NOD n 
	WHERE ax!=bx
)
-- 
SELECT MIN(ax) as NOD, a, b, max([Level]) as [Level]
FROM NOD
GROUP BY a, b;

drop table #numPairs
GO



-----------------------------------------------------------------------------------
(1 row(s) affected)
NOD         a           b           Level
----------- ----------- ----------- -----------
1           1836311903  1134903170  43


П.С.: метод вычитанием
20 май 09, 05:39    [7201476]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
П.П.С.:
2 допущения:
-- числа не равны
-- числа > 0
20 май 09, 05:45    [7201477]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
Хотя для пар чисел таких как: 2, 144 - например, лучше делением - рекурсий меньше.
Но, как по мне запрос с CTE в данном примере - это рекурсия, сказать, что это "одним запросом" по моему не совсем корректно.
?
20 май 09, 06:16    [7201486]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Чемодан
Guest
Кудряшка
Вы просто хотите в лоб написать подзапрос 45 раз?
тип чисел "на вход" решили ограничить int'ом, т.е. 2^31-1. Макс число Фибоначчи, не превышающее этот предел, есть F(47)=1836311903 (при нумерации их с единицы). По какой-то там "теореме кого-то" максимальное число итераций для получения НОД не превысит N-2 = 47-2 = 45 (где N = индекс F-числа ).
Рекурсивный способ у меня вчера тоже получился, только делением, а не вычитанием. Но хотелось без рекурсии. Впрочем, уже неважно - результат есть, коньяк выигран :-)
Всем спасибо за ответы.
20 май 09, 08:50    [7201634]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
Чемодан
Рекурсивный способ у меня вчера тоже получился, только делением, а не вычитанием. Но хотелось без рекурсии. Впрочем, уже неважно - результат есть, коньяк выигран :-)
Всем спасибо за ответы.


Я бы Вам за рекурсию коньяк не отдала
(кстати, армянским не берите, берите дагестанским!)
20 май 09, 09:39    [7201789]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
Чемодан
По какой-то там "теореме кого-то" максимальное число итераций для получения НОД не превысит N-2 = 47-2 = 45 (где N = индекс F-числа ).


Если вычитанием делать, то для чисел 1 и 1836311903 получится 1836311903 итераций. Я поэтому и уточнила, что лучше делением
20 май 09, 09:52    [7201853]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Чемодан
Guest
Кудряшка
Я бы Вам за рекурсию коньяк не отдала
я милыми дамами вообще ни на что не спорю; ни на армянский ни на дагестанский. Кстати, а откуда у вас там, в Сиднее, дагестанский может взяться ? ;-)
20 май 09, 11:43    [7202730]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Чемодан
Guest
2 Кудряшка.
Кстати, раз уж рекурсивный вариант считаем недостойным коньяка, то что можете сказать по поводу сабжа ? можете представить вариант БЕЗ рекурсии, но что бы не валился по Msg 8632 на стадии парсинга запроса ?
20 май 09, 11:45    [7202750]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
Чемодан
2 Кудряшка.
Кстати, раз уж рекурсивный вариант считаем недостойным коньяка, то что можете сказать по поводу сабжа ? можете представить вариант БЕЗ рекурсии, но что бы не валился по Msg 8632 на стадии парсинга запроса ?


Ваши 45 подзапросов можно в SQL Server 2000 попробовать ;)
в 2005 - меня терзают смутные сомнения... вот в тему
разве что совсем какой-то хитрый запрос написать, но мне ничего, кроме цикла/рекурсии в голову не приходит.

По поводу "недостойным коньяка" - это мне просто вспомнилась вчерашняя дискуссия в одной из тем, что считать одним запросом, что одним обращением к таблице в запросе и т.п.

(здесь, увы, дагестанского нэт)
20 май 09, 13:00    [7203214]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Чемодан
Guest
Кудряшка
Ваши 45 подзапросов можно в SQL Server 2000 попробовать ;)
в 2005 - меня терзают смутные сомнения... вот в тему
Прочитал (к сожалению, смог только сейчас). Спасибо, посмеялсо :-)
Там сказано, что в 2005 число имён (полей и констант), которые могут быть указаны в выражении запроса, ограничено 65535 (дословно: "SQL Server limits the number of identifiers and constants that can be contained in a single expression of a query. This limit is 65,535") Но посмотрите на простенький пример, с которого начат этот топик: какие тут 65535 имён ?! маздай жжёт, как всегда... :-/

Есть ли еще какие-нибудь соображения ?
21 май 09, 00:23    [7206775]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
Чемодан
Там сказано, что в 2005 число имён (полей и констант), которые могут быть указаны в выражении запроса, ограничено 65535 (дословно: "SQL Server limits the number of identifiers and constants that can be contained in a single expression of a query. This limit is 65,535") Но посмотрите на простенький пример, с которого начат этот топик: какие тут 65535 имён ?! маздай жжёт, как всегда... :-/


Мне тоже это не совсем понятно. Именно непонятно, вот если б обьяснил кто, как это считается. Но похоже явно в этом дело.
Например, для алгоритма вычитанием мне удалось написать 5 или 6 подзапросов, а не 4. Операторов сравнения и CASE было меньше.
Тем не менее закончилось все той же ошибкой.
21 май 09, 03:24    [7206965]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> Прочитал (к сожалению, смог только сейчас). Спасибо, посмеялсо :-)
> Там сказано, что в 2005 число имён (полей и констант), которые могут
> быть указаны в выражении запроса, ограничено 65535 (дословно: "SQL
> Server limits the number of identifiers and constants that can be
> contained in a single expression of a query. This limit is 65,535") Но
> посмотрите на простенький пример, с которого начат этот топик: какие тут
> 65535 имён ?! маздай жжёт, как всегда... :-/
>
> Есть ли еще какие-нибудь соображения ?

а вы не пробовали план выполнения своего запроса посмотреть?
того, который выполняется - с тремя уровнями вложенности.
конкретно - то выражение, которое вычисляется в compute scalar.
sql - это все-таки декларативный язык. и если вы написали
три подзапроса, это еще не значит, что сервер именно так и
будет выполнять запрос - сначала вычислит значения в самом
внутреннем подзапросе, сохранит их где-нибудь, потом на основе
этих значений вычислит значения во внешнем подзапросе и т.д.
нет - он считает, что лучше будет раскрыть все ваши подзапросы
и сразу вычислить конечное выражение. получается этакий огромный
вложенный case. в котором в случае 3-х уровней вложенности будет:
5*11*11*11 = 6655 идентификаторов и констант. соответственно,
для 4-х уровней вложенности их будет уже: 5*11*11*11*11 = 73205.
вот вам и превышение лимита.
вы же намеренно выбрали для решения своей задачи инструмент,
предназначенный для решения совсем других задач. а когда он
с этой задачей не справился, оказывается, что это "маздай жжёт".
ну да, конечно, когда разработчики сервера работали над оптимизатором
они обязательно должны были предусмотреть, что кто-то будет на
sql решать задачу по поиску НОД одним нерекурсивным запросом!

Posted via ActualForum NNTP Server 1.4

21 май 09, 08:33    [7207105]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

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

Спасибо за пазьяснения. Вы не могли бы пояснить для особо одаренных, фто такое 5 и 11, и почему "умножить" ? :)

Вот план...
 |--Compute Scalar(DEFINE:([Expr1010]=CASE WHEN CASE WHEN CASE WHEN CASE WHEN [tempdb].[dbo].[##numPairs].[n1]>=[tempdb].[dbo].[##numPairs].[n2] THEN [tempdb].[dbo].[##numPairs].[n1]%[tempdb].[dbo].[##numPairs].[n2] ELSE [tempdb].[dbo].##numPairs].n1] E
       |--Table Scan(OBJECT:([tempdb].[dbo].[##numPairs]))
21 май 09, 09:37    [7207293]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> Спасибо за пазьяснения. Вы не могли бы пояснить для особо одаренных, фто
> такое 5 и 11, и почему "умножить" ? :)

начал внимательнее подсчитывать и понял, что несколько ошибся.
ну, тем не менее.
текст запроса выглядит так:
select a,b
       ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
       ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
from(
   select a,b
         ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
         ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
   from(
     select a,b
           ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
           ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
     from(
       select a,b
             ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
             ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from(
         select a,b,ax=case when a>=b then a%b else a end,bx=case when a<b then b%a else b end
         from (select a=n1,b=n2 from ##numPairs )c
       )n
     )n
   )n
)n

попробуем раскрыть подзапросы и получить из них один case.
на самом верхнем уровне мы имеем выражение:
ax=case when ax>0 and bx>0 then case when ax>=bx then ax%bx else ax end else ax+bx end
в нем, если подсчитать, участвует 9 идентификаторов (в данном случае это алиасы - 5 раз
встречается ax и 4 раза bx) и 2 константы - 0.
каждый из алиасов раскрывается в свою очередь case-ом в, котором, опять же, содержится
9 алиасов и 2 константы. каждый из них раскрывается таким же кейсом, а каждый из алиасов
в последнем - еще одним таким же.
в самом внутреннем из case:
ax=case when ax>0 and bx>0 then case when ax>=bx then ax%bx else ax end else ax+bx end
каждый алиас раскрывается case-ом с 5 идентификаторами:
ax=case when a>=b then a%b else a end

итого, имеем выражение, в котором участвуют:
9 * (9 * (9 * (9 * 5 + 2) + 2) + 2) + 2 = 34445 идентификаторов и констант.
однако, лимит, я так понимаю, устанавливается не собственно на выражение, а
на весь оператор Compute Scalar. а в нем у нас вычисляются два таких выражения:
2*34445 = 68890. это уже больше лимита 65535.

кстати, если убрать из самого внешнего запроса одно из выражений, запрос таки-выполняется
(откуда я, собственно, и сделал вывод, что лимит дается на оператор).
select a,b
       ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
       --,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
from(
   select a,b
         ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
         ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
   from(
     select a,b
           ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
           ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
     from(
       select a,b
             ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
             ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from(
         select a,b,ax=case when a>=b then a%b else a end,bx=case when a<b then b%a else b end
         from (select a=n1,b=n2 from numPairs )c
       )n
     )n
   )n
)n

ну, вроде бы вот так.

Posted via ActualForum NNTP Server 1.4

21 май 09, 10:15    [7207499]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> однако, лимит, я так понимаю, устанавливается не собственно на выражение, а
> на весь оператор Compute Scalar.

ага, ну да:

For example, the following query only has one expression:
select a, b + c, d + e


Posted via ActualForum NNTP Server 1.4

21 май 09, 10:25    [7207547]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Кудряшка
Member

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

Спасибо!
Все понятно. До меня не сразу вот это дошло:

daw
каждый из них раскрывается таким же кейсом, а каждый из алиасов
в последнем - еще одним таким же.


Действительно! например ax используемое в выражении самого внешнего подзапроса посчитано в предыдущем (где опять CASE и 9 идентификаторов и т.д.). Точно.

Чемодан, берите свои слова обратно !
21 май 09, 10:36    [7207617]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Чемодан
Guest
daw
считает, что лучше будет раскрыть все ваши подзапросы и сразу вычислить конечное выражение
план я смотрел в первую очередь и видел, ес-сно, что case-выражение раскрывается "во всю дурь".
Увы, но не смог найти НЕрекурсивный способ, который заставил бы SS не делать этого, а выполнять инструкции именно так:
daw
сначала вычислит значения в самом внутреннем подзапросе, сохранит их где-нибудь, потом на основе этих значений вычислит значения во внешнем подзапросе и т.д

Если вам известен такой способ и вы им поделитесь, буду премного благодарен.
ЗЫ. 2 Кудряшка: и только после этого возьму свои слова обратно :-)
21 май 09, 11:46    [7208323]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> Если вам известен такой способ и вы им поделитесь, буду премного благодарен.

надо заставить его материализовать ax, bx. например, добавить
сортировку (с top) по этим столбцам.
без каких-либо гарантий, но у меня работает:
select a,b
       ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
       ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
from(
   select top 999999 a,b
         ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
         ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
   from(
     select top 999999 a,b
           ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
           ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
     from(
       select top 999999 a,b
             ,ax=case when ax>0 and bx>0 then  case when ax>=bx then ax%bx else ax end  else ax+bx end
             ,bx=case when ax>0 and bx>0 then  case when ax< bx then bx%ax else bx end  else ax+bx end
       from(
         select top 999999 a,b,ax=case when a>=b then a%b else a end,bx=case when a<b then b%a else b end
         from (select a=n1,b=n2 from numPairs )c
         order by ax, bx
       )n
     order by ax, bx
     )n
   order by ax, bx
   )n
order by ax, bx
)n


Posted via ActualForum NNTP Server 1.4

21 май 09, 11:55    [7208379]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос, но: Msg 8632, Level 17 (expression services limit). Как победить ?  [new]
Чемодан
Guest
daw
надо заставить его материализовать ax, bx
м-да, так и есть: у меня тоже заработало. Жаль, что сам не додумался до этого. Спасибо, daw!
2 Кудряшка: беру свои слова обратно: маздай не жжёт. Зажигает!
21 май 09, 12:18    [7208602]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить