Всё не то, чем кажется или о чудесах компилятора 
	   
	     | 
   
 
	
		| Предыдущая тема :: Следующая тема   | 
	 
	
	
		| Автор | 
		Сообщение | 
	 
	
		OlegFB Участник - экстремал
 
  Вступление в Клуб: 11.07.2007
  | 
		
			
				 Вт Янв 17, 2017 07:53   Всё не то, чем кажется или о чудесах компилятора | 
				     | 
			 
			
				Полезность: 1 
  | 
			 
			
				Есть в счетах-фактурах операция выгрузки СФ в xml - "Выгрузка счетов-фактур в XML (от 04.03.2015 ММВ-7-6/93@)" ::[FACTURA_DOC].[SF_PRINT_XML2015]
 
 
Посмотрим внимательно на объявление в ней параметра p_fl и внутренней переменной fio
 
 
 	  | Код: | 	 		  /******************************************************************************
 
 * Создание узла "Фамилия, имя, отчество физического лица (ФИОТип)"
 
 *****************************************************************************/
 
function createFIOOrgNode
 
      ( p_doc            &xml.DOMDocument
 
      , p_parent_node         &xml.DOMNode
 
      , p_fl            varchar2
 
      , p_name         varchar2 default null
 
      )
 
   return &xml.DOMNode
 
is
 
   nodeResult      &xml.DOMNode;   
 
   nodeChild      &xml.DOMNode;
 
   elemChild        &xml.DOMElement;
 
   fio            varchar2;
 
begin
 
   &initResultNode(nvl(p_name, 'ФИОИП'));   
 
   
 
   fio := replace(p_fl, 'ИП ');
 
 | 	  
 
На первый взгляд, ничего криминального. И параметр и переменная объявляются как тип varchar2.
 
Однако, при работе операция внезапно валиться с ошибкой несоответствия типов (переполнение буфера "Ошибка числа или значения") на строчке 
 
	 	  | Код: | 	 		  | fio := replace(p_fl, 'ИП '); | 	  
 
Как так, то?!
 
 
Смотрим в скомпилированный в PL/SQL код и всё становится понятно
 
 
	 	  | Код: | 	 		  function CREATEFIOORGNODE(P_DOC IN DBMS_XMLDOM.DOMDOCUMENT,P_PARENT_NODE IN DBMS_XMLDOM.DOMNODE,P_FL IN varchar2,P_NAME IN varchar2 := null) return DBMS_XMLDOM.DOMNODE is
 
--# 529,2
 
      NODERESULT   DBMS_XMLDOM.DOMNODE;
 
      NODECHILD   DBMS_XMLDOM.DOMNODE;
 
      ELEMCHILD   DBMS_XMLDOM.DOMELEMENT;
 
      FIO   varchar2(128); | 	  
 
 
Объявление параметра p_fl varchar2 компилятор транслировал без изменений в P_FL IN varchar2
 
А вот объявление переменной fio	varchar2 компилятор транслировал с модификацией в FIO varchar2(128)
 
 
Нормально да?
 
В таком виде, при вызове функции, ей можно передать в P_EL строчку длинной, например, 200 символов, и она её проглотит, но поперхнётся при выполнении простой операции присваивания внутри себя.
 
 
Вывод: Всегда и везде явно определяйте длину строковых (символьных) переменных.
 
 
Вывод два: оборвать руки цфт-шным программистам! | 
			 
		  | 
	 
	
		  | 
	 
	
		Эмиралька Эксперт
 
  Вступление в Клуб: 09.11.2015
  | 
		
			
				 Вт Янв 17, 2017 10:55   Re: Всё не то, чем кажется или о чудесах компилятора | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | OlegFB пишет: | 	 		  Вывод: Всегда и везде явно определяйте длину строковых (символьных) переменных.
 
 
Вывод два: оборвать руки цфт-шным программистам! | 	  
 
 
В документации по pl+ вроде объясняется, что умолчательной длиной ПЕРЕМЕННОЙ varchar2 в pl+ является 128 символов и также всё везде талдычат "всегда указывайте длину переменной, особенно параметра"!
 
А у параметра вообще длины нет, не только в pl+, но и в Oracle, она появляется только когда IN-параметр начинают переприсваивать.
 
А вообще, я согласна, pl+ большой помощник по генерации скрытых ошибок и нифига не помогает их избегать. | 
			 
		  | 
	 
	
		  | 
	 
	
		KhrushchevAV Участник со стажем
 
  Вступление в Клуб: 17.10.2014
  | 
		
			
				 Чт Янв 19, 2017 09:08    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Цитата: | 	 		  Вывод: Всегда и везде явно определяйте длину строковых (символьных) переменных. 
 
 
Вывод два: оборвать руки цфт-шным программистам! | 	  
 
 
+2
 
 
И спасибо, что напомнили. Полезно.
 
Потратишь бывает полдня, на подобную замаскированную ошибку. Придешь к таким же выводам.
 
А через полгода почему-то забывается. И потом опять на те же грабли... | 
			 
		  | 
	 
	
		  | 
	 
	
		OlegFB Участник - экстремал
 
  Вступление в Клуб: 11.07.2007
  | 
		
			
				 Чт Янв 19, 2017 09:57    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | KhrushchevAV пишет: | 	 		   	  | Цитата: | 	 		  Вывод: Всегда и везде явно определяйте длину строковых (символьных) переменных. 
 
 
Вывод два: оборвать руки цфт-шным программистам! | 	  
 
 
+2
 
 
И спасибо, что напомнили. Полезно.
 
Потратишь бывает полдня, на подобную замаскированную ошибку. Придешь к таким же выводам.
 
А через полгода почему-то забывается. И потом опять на те же грабли... | 	  
 
 
И всё бы ничего... Но это дистрибутивная операция   | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
  | 
   
 
		 |