Используя этот пример:
create table t_val
(id number(10,0),
value number(5,2));
declare
v_dummy number;
begin
delete from t_val;
for i in 9 .. 20 loop
insert into t_val values (i, 1/i);
select count(*)
into v_dummy
from t_val
where value = 1/i;
dbms_output.put_line(to_char(i,'00')||':'||v_dummy||':'||
to_char(1/i,'000.999999'));
end loop;
--
end;
/
select id, value from t_val order by 1;
Вы можете видеть, что код вставляет, например, 0,11111, который неявно округляется до 0,11
Когда код сразу пытается подсчитать значения для 0,11111, он не находит совпадений.
Аналогичным образом значения для (1/14) и (1/15) округляются до 0,07.
Это не проблема, специфичная для PL / SQL, и я видел похожие проблемы в коде Java и PHP, когда значение в «клиенте» округляется, когда оно попадает в базу данных. PL / SQL предлагает лучшее решение, так как вы можете объявить переменную типа определенной таблицы / столбца, и эта привязка сохраняется, даже если столбец изменяется.
declare
v_value t_val.value%type;
v_dummy number;
begin
delete from t_val;
for i in 9 .. 20 loop
v_value := 1/i;
insert into t_val values (i, v_value);
select count(*)
into v_dummy
from t_val
where value = v_value;
dbms_output.put_line(to_char(i,'00')||':'||v_dummy||':'||
to_char(1/i,'000.999999')||':'||to_char(v_value,'000.999999'));
end loop;
--
end;
/
Таким образом, при работе с оператором SQL рекомендуется использовать переменные связывания, привязанные к типу (включая длину / масштаб / точность) базовой таблицы.