Подстановка условий в if из макроса 
	   
	     | 
   
 
	
		| Предыдущая тема :: Следующая тема   | 
	 
	
	
		| Автор | 
		Сообщение | 
	 
	
		ff3796a1 Участник
 
  Вступление в Клуб: 16.05.2017
  | 
		
			
				 Вт Май 16, 2017 11:37   Подстановка условий в if из макроса | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				Здравствуйте.
 
 
Прошу помочь в решении такого вопроса:
 
 
Необходимо организовать возможность оперативно (без перекомпиляций) изменять условия одного if в тексте операции. Для этого создал в справочнике Настройки. параметр LET_COL, заполнил его примерно так:
 
 
((upper(subj) like '%БУХ%') or (upper(subj) like '%ОТЧ_ТНОСТЬ%') or (upper(subj) like '%БАЛАНС%') or ...)
 
 
Смысл в том, что есть куча лайков.
 
 
Далее в тексте операции вытаскиваю значение, присваиваю его в переменную. Объявляю макрос.
 
 
nastr:= ::[FP_TUNE].[LIB].get_str_value('LET_COL');
 
pragma MACRO(usl_nastr, nastr); --Макрос для подстановки условий
 
 
Далее пишу IF:
 
 
if &usl_nastr
 
	then {...} end if;
 
 
В результате в IF проваливается всегда, условия не проверяются. 
 
 
Как можно написать код в данном случае?
 
 
Заранее благодарен. | 
			 
		  | 
	 
	
		  | 
	 
	
		vtar Эксперт
 
  Вступление в Клуб: 20.03.2009
  | 
		
			
				 Вт Май 16, 2017 15:15   Re: Подстановка условий в if из макроса | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | ff3796a1 пишет: | 	 		  Смысл в том, что есть куча лайков.
 
 
 | 	  
 
 
тут Вам не фейсбук ...
 
 
первое - в настройке галка "кэшировать" стоит ?
 
 
если да то надо перезаходить в АРМ либо снять галку чтобы не кэшировалась.
 
 
сам метод какой то кривой, лучше пользуйте динамический SQL что ли ... | 
			 
		  | 
	 
	
		  | 
	 
	
		Эмиралька Эксперт
 
  Вступление в Клуб: 09.11.2015
  | 
		
			
				 Ср Май 17, 2017 04:39   Re: Подстановка условий в if из макроса | 
				     | 
			 
			
				Полезность: 3 
  | 
			 
			
				 	  | ff3796a1 пишет: | 	 		  Необходимо организовать возможность оперативно (без перекомпиляций) изменять условия одного if в тексте операции. Для этого создал в справочнике Настройки. параметр LET_COL, заполнил его примерно так:
 
 
((upper(subj) like '%БУХ%') or (upper(subj) like '%ОТЧ_ТНОСТЬ%') or (upper(subj) like '%БАЛАНС%') or ...)
 
 
Смысл в том, что есть куча лайков.
 
 
Далее в тексте операции вытаскиваю значение, присваиваю его в переменную. Объявляю макрос.
 
 
nastr:= ::[FP_TUNE].[LIB].get_str_value('LET_COL');
 
pragma MACRO(usl_nastr, nastr); --Макрос для подстановки условий
 
 
Далее пишу IF:
 
 
if &usl_nastr
 
	then {...} end if;
 
 
В результате в IF проваливается всегда, условия не проверяются. 
 
 
Как можно написать код в данном случае? | 	  
 
Макрос является элементом предкомпиляции, все условия в макросе проверяются только при компиляции кода. Результатом работы макроса является код, который и компилируется и в дальнейшем исполняется. То есть, если у Вас на разных серверах разные условия, но они постоянны, то имеет смысл проверить, на какой сервер устанавливается функционал один раз - при компиляции. 
 
В Вашем случае код, написанный до объявления макроса, он ВНЕ макроса и при компиляции не выполняется, то есть остаётся просто каким-то текстом; макрос, который Вы написали - не подставляет прочитанные условия из настроек, а тупо явлется текстом "nastr". Соответственно, условие if &usl_nastr у вас для компилятора звучит как if nastr then, а так как PL+ является языком, который пытается думать за Вас, то PL+ предположил, что Вы имели в виду if nastr is not null then. Или как-то так, надо смотреть скомпилированный код.
 
В общем, фигня у Вас написана.
 
Рекомендуется оформить проверку обычным кодом, а не макросом.
 
Например, как предложил vTar, динамически:
 
 	  | Код: | 	 		  declare
 
   function uif(p_cond varchar2, p_var varchar2, p_value varchar2) return boolean is
 
      vText   varchar2(32767);
 
      iTmp   integer;
 
      nState number;
 
   begin -- uif
 
      vText := 'begin if '||replace(p_cond, p_var, ''''||p_value||'''')||' then :ret := 1; else :ret := 0; end if; end;';
 
      nState := rtl.exec_sql_out(vText, 'ret', iTmp);
 
      return iTmp = 1;
 
   end; -- uif
 
begin -- anonymous block
 
   dbms_output.put_line(rtl.bool_char(uif('subj is null', 'subj', null), 'true', 'false'));
 
   dbms_output.put_line(rtl.bool_char(uif('subj like ''123%''', 'subj', '12345'), 'true', 'false'));
 
end; -- anonymous block
 
 | 	  
 
 
Либо сделать исполняемый макрос, результатом которого будет код со множеством лайков   Но все манипуляции с объектами БД должны производиться ВНУТРИ макроса.
 
 	  | Код: | 	 		  
 
pragma macro (cond,
 
'z$fp_tune_lib.get_str_value([1])'
 
   ,process,substitute);
 
if &cond('LET_COL') then
 
 ...
 
 | 	  
 
однако обращаю Ваше внимание, что вызов функции (и доступ к данным) будет осуществлён только один раз - при компиляции и из-под пользователя IBS.
 
 	  | ff3796a1 пишет: | 	 		  | Заранее благодарен. | 	  
 
для благодарности есть кнопка "Оценить сообщение"    | 
			 
		  | 
	 
	
		  | 
	 
	
		ff3796a1 Участник
 
  Вступление в Клуб: 16.05.2017
  | 
		
			
				 Ср Май 17, 2017 12:48    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				| Спасибо, попробую реализовать динамический SQL. | 
			 
		  | 
	 
	
		  | 
	 
	
		Alkov Профи
 
  Вступление в Клуб: 23.09.2010
  | 
		
			
				 Пн Май 22, 2017 05:34    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				можно было просто загнать фразы в массив в настройке 
 
ОТЧ_ТНОСТЬ
 
БУХ
 
...
 
а потом select  по массиву делать | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
  | 
   
 
		 |