Можете ли вы показать типы данных и рабочую хранимую процедуру, иллюстрирующую проблему?
Не должно быть никакого особого значения, чтобы расставить точки в этом контексте. Это строка, и никакое числовое значение не должно быть равно ей; если число преобразуется в строку, то не будет ничего (для NULL) или хотя бы одной цифры, ни одна из которых не совпадает со строкой '.', и если строка '.'
преобразуется в число, это преобразование должно завершиться неудачно (возможно, при создании процедуры, конечно, во время выполнения).
Одна вещь, которая меня удивляет, это то, что показанный вами синтаксис не является синтаксисом SPL. SPL не использует 'end if', хотя I4GL использует. Действительно, SPL (язык хранимых процедур) использует END только в сочетании с совпадающим BEGIN.
Похоже, что у меня не хватает памяти и что я не должен пытаться читать руководства до полуночи.
Также кажется, что этот код делает то, чего я не ожидал ...
+ set debug file to "/tmp/x1";
SET DEBUG FILE TO: Rows processed = 0
+ drop procedure so2139024();
DROP PROCEDURE: Rows processed = 0
+ create procedure so2139024() returning int as rv;
define value numeric(5,1);
define rv integer;
trace on;
let rv = 0;
let value = 0.0;
if value = '.' then
let rv = 1;
end if;
return rv;
end procedure;
CREATE PROCEDURE: Rows processed = 0
+ execute procedure so2139024();
1
EXECUTE PROCEDURE: Rows processed = 1
Итак, по какой-то причине сравнение работает; значение ноль сравнивается равным точке. Это было протестировано на MacOS X 10.6.2 с IBM Informix Dynamic Server 11.50.FC6 (и SQLCMD 86.04, созданным с CSDK 3.50.FC4, но работающим с 3.50.FC6).
Файл отладки содержит:
trace on
expression:(= value, ".")
evaluates to t
let rv = 1
expression:rv
evaluates to 1
procedure so2139024 returns 1
iteration of cursory procedure so2139024
Априори об этом следует сообщать через службу технической поддержки IBM / Informix. Я думаю, что это, скорее всего, какая-то ошибка, но я не знаю, как это найти ответ. Я тоже проверю через задние каналы.
Внутренние каналы показывают, что вероятная проблема заключается в том, что функция deccvasc()
в библиотеке ESQL / C (также используется сервером для внутреннего использования) неправильно обрабатывает строку '.'.
Тестовый код ESQL / C здесь показывает, что:
#include <stdio.h>
#include "dumpesql.h"
int main(void)
{
dec_t d;
int rc = deccvasc(".", 1, &d);
printf("rc = %d\n", rc);
dump_decimal(stdout, "Decimal", &d);
return(0);
}
Функция dump_decimal () является нестандартной, но выводит информацию из десятичной структуры. Выход:
rc = 0
DECIMAL: Decimal -- address 0x7FFF5FBFF090
E: -64, S = 1 (+), N = 0, M = value is ZERO
Следовательно, сервер (по ошибке) принимает '.' как правильное представление нуля, а не сообщение об ошибке. В настоящее время вам придется отредактировать хранимую процедуру, чтобы сделать ее более понятной - неясно, чего должен достичь тест, но она явно написана неправильно. (Это не отрицает наличие ошибки на сервере.) Пожалуйста, сообщите об этом в службу технической поддержки IBM / Informix.