CftClub.ru
Клуб специалистов ЦФТ-Банк

Всё не то, чем кажется или о чудесах компилятора

 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Справочник PL/PLUS: Функции, примеры, приёмы
Предыдущая тема :: Следующая тема  
Автор Сообщение
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

И спасибо, что напомнили. Полезно.
Потратишь бывает полдня, на подобную замаскированную ошибку. Придешь к таким же выводам.
А через полгода почему-то забывается. И потом опять на те же грабли...


И всё бы ничего... Но это дистрибутивная операция Sad
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Справочник PL/PLUS: Функции, примеры, приёмы Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru