Размерность строковой переменной 
	   
	     | 
   
 
	
		| Предыдущая тема :: Следующая тема   | 
	 
	
	
		| Автор | 
		Сообщение | 
	 
	
		danzki Участник - экстремал
 
  Вступление в Клуб: 30.09.2010
  | 
		
			
				 Ср Авг 20, 2014 10:08   Размерность строковой переменной | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				Коллеги,
 
обнаружил проблему с функциями, возвращающими строку.
 
Покажу на примере.
 
 
Глобальное описание
 
 	  | Код: | 	 		  | function Get_client_acc(cl ref [CLIENT]) return varchar2(32000); | 	  
 
 
Локальное описание (только заголовок)
 
 	  | Код: | 	 		  function Get_client_acc(cl ref [CLIENT]) return varchar2(32000) is
 
acc_client varchar2(32000)  := NULL;
 
begin
 
...
 
return acc_client;
 
end; | 	  
 
 
Если посмотреть PL/SQL пакет (по F12), то обнаружим неприятную штуку
 
 
Спецификация
 
 	  | Код: | 	 		  | function GET_CLIENT_ACC(CL IN number) return varchar2; | 	  
 
 
Боди пакета
 
 	  | Код: | 	 		  function GET_CLIENT_ACC(CL IN number) return varchar2 is
 
   ACC_CLIENT   varchar2(32000) := null;
 
begin
 
...
 
RETURN ACC_CLIENT;
 
end;
 
 | 	  
 
 
Т.е. для возвращаемого значения размерность пропадает.
 
 
При этом если пытаемся вернуть больше 4000 все валится - character string buffer too small
 
 
Кто-нибудь сталкивался? | 
			 
		  | 
	 
	
		  | 
	 
	
		vtar Эксперт
 
  Вступление в Клуб: 20.03.2009
  | 
		 | 
	 
	
		  | 
	 
	
		Alex294 Участник со стажем
 
  Вступление в Клуб: 02.06.2013
  | 
		
			
				 Ср Авг 20, 2014 11:16    | 
				     | 
			 
			
				Полезность: 1 
  | 
			 
			
				На самом деле это ограничение Oracle SQL, для PL/SQL такого ограничения нет. 
 
Функция:
 
 	  | Код: | 	 		  function Gen_memo return varchar2(32767)
 
is
 
begin
 
   return RPAD('A', 5000, 'a');
 
end;
 
 | 	  
 
хотя преобразуется в:
 
 	  | Код: | 	 		     function GEN_MEMO return varchar2 is
 
   begin
 
--# 9,2
 
      return RPAD('A',5000,'a');
 
   end;
 
 | 	  
 
отрабатывает на ура:
 
 	  | Код: | 	 		  If P_MESSAGE = 'DEFAULT' then
 
   P_MSG := Gen_memo();
 
end if; | 	  
 
P-MSG имеет тип Мемо_32767. | 
			 
		  | 
	 
	
		  | 
	 
	
		Random Эксперт
 
  Вступление в Клуб: 27.06.2011
  | 
		
			
				 Ср Авг 20, 2014 13:23   Re: Размерность строковой переменной | 
				     | 
			 
			
				Полезность: 2 
  | 
			 
			
				 	  | danzki пишет: | 	 		  Коллеги,
 
обнаружил проблему с функциями, возвращающими строку.
 
Покажу на примере.
 
 
Глобальное описание
 
 	  | Код: | 	 		  | function Get_client_acc(cl ref [CLIENT]) return varchar2(32000); | 	  
 
 
Локальное описание (только заголовок)
 
 	  | Код: | 	 		  function Get_client_acc(cl ref [CLIENT]) return varchar2(32000) is
 
acc_client varchar2(32000)  := NULL;
 
begin
 
...
 
return acc_client;
 
end; | 	  
 
 
Если посмотреть PL/SQL пакет (по F12), то обнаружим неприятную штуку
 
 
Спецификация
 
 	  | Код: | 	 		  | function GET_CLIENT_ACC(CL IN number) return varchar2; | 	  
 
 
Боди пакета
 
 	  | Код: | 	 		  function GET_CLIENT_ACC(CL IN number) return varchar2 is
 
   ACC_CLIENT   varchar2(32000) := null;
 
begin
 
...
 
RETURN ACC_CLIENT;
 
end;
 
 | 	  
 
 
Т.е. для возвращаемого значения размерность пропадает.
 
 
При этом если пытаемся вернуть больше 4000 все валится - character string buffer too small
 
 
Кто-нибудь сталкивался? | 	  
 
 
при объявлении возвращаемого типа из функции в PL/SQL и PL/PLUS можно объявить только тип данных, но никак не размерность.
 
 	  | Код: | 	 		  | function test return varchar2(100) is | 	   - в PL/SQL просто не скомпилируется. А в PL/PLUS будет заменена на валидный тип без всяких размерностей. Аналогично для параметров, кстати.
 
 
Размерность определяется переменной или функцией или константой, которая реально возвращается.
 
 
Например, в PL/PLUS  	  | Код: | 	 		  function test return varchar2(100) is
 
vRet varchar2(1000); -- а вот и реальный размер !!!
 
begin
 
   vRet := lpad(' ',1000,' ');
 
  return vRet;
 
end;
 
 | 	   прекрасно НЕ ломается. Но ломает шаблон разработчику, поэтому, ПОЖАЛУЙСТА, не используйте размерности ни в параметрах функций, ни в результирующих значениях...
 
 
А у вас дело в том, что вы проверяете функцию с помощью SQL-запроса.
 
 	  | Код: | 	 		  | select Z$имя пакета.GET_CLIENT_ACC(z.id) from z#client z | 	  
 
В SQL максимальный размер строки - 4000, а в PL/SQL - 32767 символов. Соответственно, функция вполне может вернуть строчку больше 4к:
 
 	  | Код: | 	 		  declare
 
v varchar2(32767);
 
begin
 
  v := rtl.open;
 
  select id into v from z#client where rownum < 2;
 
  v := Z$имя пакета.GET_CLIENT_ACC(v);
 
end; | 	  
 
вот только использовать эту функцию в запросах и представлениях уже не получится. | 
			 
		  | 
	 
	
		  | 
	 
	
		danzki Участник - экстремал
 
  Вступление в Клуб: 30.09.2010
  | 
		
			
				 Ср Авг 20, 2014 14:22    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				| Random, Alex294, спасибо за исчерпывающий ответ. Все так и есть | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
  | 
   
 
		 |