Всё не то, чем кажется или о чудесах компилятора
|
Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
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
И спасибо, что напомнили. Полезно.
Потратишь бывает полдня, на подобную замаскированную ошибку. Придешь к таким же выводам.
А через полгода почему-то забывается. И потом опять на те же грабли... |
И всё бы ничего... Но это дистрибутивная операция  |
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|