CASE WHEN THEN ошибка 
	  На страницу  Пред.  1, 2 
	     | 
   
 
	
		| Предыдущая тема :: Следующая тема   | 
	 
	
	
		| Автор | 
		Сообщение | 
	 
	
		vtar Эксперт
 
  Вступление в Клуб: 20.03.2009
  | 
		
			
				 Вс Июл 22, 2018 20:26    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				здоров!
 
 
Client_v , не _r
 
 
попробуй через оr | 
			 
		  | 
	 
	
		  | 
	 
	
		Матвеев Евгений Профи
 
  Вступление в Клуб: 31.01.2012
  | 
		
			
				 Пн Июл 23, 2018 17:44    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | vtar пишет: | 	 		  здоров!
 
 
Client_v , не _r
 
 
попробуй через оr | 	  
 
 
 
Итого пара вариантов
 
 
--------------------------------------------------------
 
1. Без CASE и UNION...         Стоимость Plan hash value: 1322325846
 
 
 
			select z(sum(z.c)) in
 
			(
 
 
 
				select  x(count(x) :c ) in ::[AC_FIN] all
 
				where	
 
				(	
 
					(
 
						class_ = 'CL_ORG'
 
						and
 
						x.[CLIENT_V] in (p_client)
 
					)
 
					or
 
					(
 
						class_ = 'CL_PRIV'
 
						and
 
						x.[CLIENT_V] in
 
										( select  w(w.[PARTNER])
 
										  in ::[LINKS_CL]
 
										  ,(::[CL_ORG] all: org) all
 
										  where   w%collection = p_client.[LINKS_OTHER]
 
										  and	  w.[PARTNER]  = org
 
										)
 
					)
 
				)													
 
				and
 
					(
 
						(
 
							x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')
 
						)
 
					or
 
						(
 
							x.[COM_STATUS] is null
 
						)
 
					)
 
 
 
--------------------------------------------------------
 
2. Без CASE и с 1им UNION...         Стоимость Plan hash value: 3895021466
 
 
				----------------------------------------	
 
 
				select x(count(x) :c ) in ::[AC_FIN] all
 
					where	x.[CLIENT_V] in (p_client)
 
						and	class_ in ('CL_ORG')	
 
						and
 
							(
 
								(
 
									x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')
 
								)
 
							or
 
								(
 
									x.[COM_STATUS] is null
 
								)
 
							)						
 
				union all
 
				----------------------------------------	
 
				select x(count(x) :c ) in ::[AC_FIN] all
 
					where	x.[CLIENT_V] in
 
						(select w(w.[PARTNER])
 
							in ::[LINKS_CL]
 
							,(::[CL_ORG] all: org) all
 
							where w%collection = p_client.[LINKS_OTHER]
 
							and	w.[PARTNER] = org
 
						)
 
						and	class_ in ('CL_PRIV')	
 
						and
 
							(
 
								(
 
									x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')
 
								)
 
							or
 
								(
 
									x.[COM_STATUS] is null
 
								)
 
							)						
 
 
 
Судя по стоимости 1 вариант наиболее кошерный | 
			 
		  | 
	 
	
		  | 
	 
	
		Volod Эксперт
 
  Вступление в Клуб: 19.09.2007
  | 
		
			
				 Вт Июл 24, 2018 09:14    | 
				     | 
			 
			
				Полезность: 1 
  | 
			 
			
				Зачем городить Union? Через  	  | Код: | 	 		  | If class_ = 'CL_PRIV' then  | 	    не проще? | 
			 
		  | 
	 
	
		  | 
	 
	
		Матвеев Евгений Профи
 
  Вступление в Клуб: 31.01.2012
  | 
		
			
				 Вт Июл 24, 2018 09:24    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Volod пишет: | 	 		  Зачем городить Union? Через  	  | Код: | 	 		  | If class_ = 'CL_PRIV' then  | 	    не проще? | 	  
 
 
Если через if на два запроса придется разбивать) | 
			 
		  | 
	 
	
		  | 
	 
	
		Volod Эксперт
 
  Вступление в Клуб: 19.09.2007
  | 
		
			
				 Вт Июл 24, 2018 09:30    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				| И что? Это же count into. | 
			 
		  | 
	 
	
		  | 
	 
	
		Эмиралька Эксперт
 
  Вступление в Клуб: 09.11.2015
  | 
		
			
				 Вт Июл 24, 2018 10:26    | 
				     | 
			 
			
				Полезность: 1 
  | 
			 
			
				что-то смотрю на код и не понимаю.
 
Если class_ - это переменная, то зачем организовыать ветвление в запросе, проще организовать через обычный if then elsif.
 
 
 	  | Код: | 	 		  
 
if class_ = 'CL_ORG' then
 
   select x(count(1)) in ::[AC_FIN] all 
 
   where   x.client_v = p_client
 
   and   x.[COM_STATUS] != ::[COM_STATUS_PRD]([ CODE]='TO_OPEN')
 
   into nCnt;
 
 
elsif class_ = 'CL_PRIV' then
 
   select x(count(1)) in ::[AC_FIN] all
 
   where   x.client_v in (
 
 
select w(org) 
 
in ::[LINKS_CL] 
 
,(::[CL_ORG] all: org) all 
 
where w%collection = p_client.[LINKS_OTHER] 
 
and   w.[PARTNER] = org
 
 
)
 
   and   x.[COM_STATUS] != ::[COM_STATUS_PRD]([ code]='TO_OPEN')
 
   into nCnt;
 
 
else
 
   nCnt := 0;
 
end if;
 
 | 	  
 
 
а если уж так необходимо сделать всё именно через SQL, то так:
 
 	  | Код: | 	 		  
 
select z(case when class_ = 'CL_ORG' then
 
(
 
   select x(count(1)) in ::[AC_FIN] all 
 
   where   x.client_v = p_client
 
   and   x.[COM_STATUS] != ::[COM_STATUS_PRD]([ CODE]='TO_OPEN')
 
)
 
 
when class_ = 'CL_PRIV' then
 
(
 
   select x(count(1)) in ::[AC_FIN] all
 
   where   x.client_v in (
 
 
select w(org) 
 
in ::[LINKS_CL] 
 
,(::[CL_ORG] all: org) all 
 
where w%collection = p_client.[LINKS_OTHER] 
 
and   w.[PARTNER] = org
 
 
)
 
   and   x.[COM_STATUS] != ::[COM_STATUS_PRD]([ code]='TO_OPEN')
 
)
 
 
else
 
   0
 
end
 
 
) in dual%rowtype
 
into nCnt;
 
 | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		Матвеев Евгений Профи
 
  Вступление в Клуб: 31.01.2012
  | 
		
			
				 Вт Июл 24, 2018 10:43    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Эмиралька пишет: | 	 		  что-то смотрю на код и не понимаю.
 
Если class_ - это переменная, то зачем организовыать ветвление в запросе, проще организовать через обычный if then elsif.
 
 
 	  | Код: | 	 		  
 
if class_ = 'CL_ORG' then
 
   select x(count(1)) in ::[AC_FIN] all 
 
   where   x.client_v = p_client
 
   and   x.[COM_STATUS] != ::[COM_STATUS_PRD]([ CODE]='TO_OPEN')
 
   into nCnt;
 
 
elsif class_ = 'CL_PRIV' then
 
   select x(count(1)) in ::[AC_FIN] all
 
   where   x.client_v in (
 
 
select w(org) 
 
in ::[LINKS_CL] 
 
,(::[CL_ORG] all: org) all 
 
where w%collection = p_client.[LINKS_OTHER] 
 
and   w.[PARTNER] = org
 
 
)
 
   and   x.[COM_STATUS] != ::[COM_STATUS_PRD]([ code]='TO_OPEN')
 
   into nCnt;
 
 
else
 
   nCnt := 0;
 
end if;
 
 | 	  
 
 
а если уж так необходимо сделать всё именно через SQL, то так:
 
 	  | Код: | 	 		  
 
select z(case when class_ = 'CL_ORG' then
 
(
 
   select x(count(1)) in ::[AC_FIN] all 
 
   where   x.client_v = p_client
 
   and   x.[COM_STATUS] != ::[COM_STATUS_PRD]([ CODE]='TO_OPEN')
 
)
 
 
when class_ = 'CL_PRIV' then
 
(
 
   select x(count(1)) in ::[AC_FIN] all
 
   where   x.client_v in (
 
 
select w(org) 
 
in ::[LINKS_CL] 
 
,(::[CL_ORG] all: org) all 
 
where w%collection = p_client.[LINKS_OTHER] 
 
and   w.[PARTNER] = org
 
 
)
 
   and   x.[COM_STATUS] != ::[COM_STATUS_PRD]([ code]='TO_OPEN')
 
)
 
 
else
 
   0
 
end
 
 
) in dual%rowtype
 
into nCnt;
 
 | 	 
  | 	  
 
 
Приветствую Эмиралька...
 
У меня вариант 
 
[code]
 
		if class_ = 'CL_ORG' then
 
 
				select  x(count(x) : c) in ::[AC_FIN] all
 
					where	
 
						x.[CLIENT_V] = p_client
 
					and 
 
						( 
 
							( 
 
								x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN') 
 
							) 
 
							or 
 
							( 
 
								x.[COM_STATUS] is null 
 
							) 
 
						)	
 
					into  cnt;
 
		
 
		elsif class_ = 'CL_PRIV' then
 
 
				select  x(count(x) : c) in ::[AC_FIN] all			
 
				where	x.[CLIENT_V] in 	
 
												( select  w(w.[PARTNER])
 
												  in ::[LINKS_CL]
 
												  ,(::[CL_ORG] all: org) all
 
												  where   w%collection = p_client.[LINKS_OTHER]
 
												  and	  w.[PARTNER]  = org
 
												)
 
				and 
 
				( 
 
					( 
 
						x.[COM_STATUS] != ::[COM_STATUS_PRD]([code]='TO_OPEN') 
 
					) 
 
					or 
 
					( 
 
						x.[COM_STATUS] is null 
 
					) 
 
				)	
 
				into  cnt;
 
 
			
 
 
			
 
		else	
 
			pragma error('Клиент ID = '||p_client||' имеет класс '||class_||' для которого не определен алгоритм разрешения синхронизации !');
 
		end if;
 
 
	end if;
 
[/code]
 
 
Между вариантами разница лишь в
 
 
					or 
 
					( 
 
						x.[COM_STATUS] is null 
 
					) 
 
 
и
 
 
x(count(x)
 
x(count(1))
 
 
Если прибегут пользователи с вилами и вопросами, то мне проще им сказать что предыдущие разработчики ) предусмотрели именно такие условия проверок aka x.[COM_STATUS] is null )))
 
 
Протестировал, запросов 20 прогнал (составная часть интеграции) ... замечаний нет... видимо карйний вариант пойдет в прод | 
			 
		  | 
	 
	
		  | 
	 
	
		Эмиралька Эксперт
 
  Вступление в Клуб: 09.11.2015
  | 
		
			
				 Ср Июл 25, 2018 07:33    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Матвеев Евгений пишет: | 	 		   	  | Эмиралька пишет: | 	 		  что-то смотрю на код и не понимаю.
 
Если class_ - это переменная, то зачем организовыать ветвление в запросе, проще организовать через обычный if then elsif.
 
[skip]
 
 | 	  
 
 
Приветствую Эмиралька...
 
У меня вариант 
 
 	  | Код: | 	 		  
 
      if class_ = 'CL_ORG' then
 
[skip]
 
      elsif class_ = 'CL_PRIV' then
 
[skip]
 
      else   
 
[skip]
 
      end if;
 
 | 	  
 
[skip]
 
 
Протестировал, запросов 20 прогнал (составная часть интеграции) ... замечаний нет... видимо карйний вариант пойдет в прод | 	  
 
Ой, простите, Volod выше упоминал про ifы    
 
Ну что ж, значит, это и правда хороший вариант   | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
  | 
   
 
		 |