У меня есть следующая процедура, которая обновляет информацию о клиенте в зависимости от входных параметров.
-- Update client
create or replace procedure p_update_client (i_client_id in number, i_iin in number default null, i_full_name in varchar default null)
as
query_str varchar(200);
no_id_provided exception;
all_null_values exception;
begin
-- Handle input parameters
if i_client_id is null then
raise no_id_provided;
end if;
if i_iin is null and i_full_name is null then
raise all_null_values;
end if;
-- Base query string.
query_str := 'update t_client set';
-- Form SQL depending on the input parameters.
if i_iin is not null then
query_str := query_str || ' iin = :param1';
end if;
if i_full_name is not null then
query_str := query_str || ' full_name = :param2';
end if;
-- Add necessary where clause to identify record.
query_str := query_str || ' where client_id = :param3;';
-- Execute query.
execute immediate query_str using i_iin, i_full_name, i_client_id;
exception
when no_id_provided then
raise_application_error(-20100, 'Client_id value must not be null.');
when all_null_values then
raise_application_error(-20101, 'To update record, input parameters must not be null.');
when others then
rollback;
end p_update_client;
Итак, логика процедуры следующая: если переданный параметр имеет ненулевое значение, то я динамически обновляю свойSQL и выполните его, используя execute immidiate
.Это прекрасно работает, если оба параметра имеют ненулевые значения.Если один из параметров имеет значение NULL, query_str
выдаст ошибку SQL ORA-01006: bind variable does not exist
, поскольку число параметров, указанное в query_str
, не совпадает с параметром using
.
Что такоелучший способ справиться с такой ситуацией, возможно, некоторые именованные параметры, но, как я знаю, execute emmidiate
этого не обеспечивает.Есть идеи?