Как я могу использовать переменную связывания в функции plsql

У меня есть такая функция:

create or replace function params
(
    p_pr     varchar2,
    p_qu_id  varchar2,
    p_date   date := sysdate,
    p_param  varchar2 := null
)
    return   varchar2
as
    ...
    sql_stmt varchar2(4000);
    rc       sys_refcursor;
    ...
BEGIN
    sql_stmt := 'select parameter_name, parameter_value from ' || p_pr | '.v_view where query_id = ''' || p_qu_id || '''';

    IF p_param IS NOT NULL
    THEN
        sql_stmt := sql_stmt || ' and parameter_value=''' || p_param || '''';
    END IF;

    OPEN rc FOR sql_stmt;
    LOOP
        FETCH rc
            INTO v_param_name, v_param_value;
        EXIT WHEN rc%NOTFOUND;
        EXIT WHEN v_param_value is NULL;

        ....

DBA сказал, что эта функция использует жесткий анализ, я должен использовать переменную связывания в этой функции. Как я могу это сделать?

Спасибо.


person onur    schedule 19.12.2017    source источник
comment
docs.oracle.com/ база данных/121/LNPLS/   -  person a_horse_with_no_name    schedule 19.12.2017
comment
Здесь не хватает трубы: ... from ' || p_pr |. Вы не сможете привязать переменную p_pr к запросу, поскольку она является частью имени таблицы, но вы можете использовать dbms_assert, чтобы убедиться, что оно соответствует критериям допустимого имени идентификатора. Однако вы можете привязать параметр_значение и открыть курсор, передав значение p_param. см. здесь пример того, как сделай это.   -  person Boneist    schedule 19.12.2017


Ответы (1)


Я должен использовать переменную связывания в этой функции.

Решение состоит в том, чтобы использовать заполнитель в шаблоне SQL...

sql_stmt := sql_stmt || ' and parameter_value= :p1';

... затем передайте фактическое значение с предложением USING при открытии курсора ref.

Все немного сложно, потому что вы выполняете разные операторы в зависимости от того, заполнен ли параметр. Поэтому вам нужно сделать что-то вроде этого:

sql_stmt := 'select parameter_name, parameter_value from ' || p_pr 
     || '.v_view where query_id =:p1';

IF p_param IS NOT NULL
THEN
    sql_stmt := sql_stmt || ' and parameter_value= :p2';
    OPEN rc FOR sql_stmt using p_qu_id, p_param;
else
   OPEN rc FOR sql_stmt using p_qu_id;
END IF;

LOOP

Обратите внимание, что p_pr — имя схемы — нельзя заменить переменной связывания.

person APC    schedule 19.12.2017
comment
Условная привязка выглядит следующим образом: oracle .com/technetwork/issue-archive/2009/09-июль/ - person William Robertson; 19.12.2017
comment
@williamrobertson - да, это еще один способ сделать это. Мне кажется, что у нас действительно два разных запроса. Есть разница между переписыванием кода для использования переменных связывания и переписыванием кода для выполнения только одного запроса независимо от того, какие параметры мы передаем. Я нахожу мою версию более понятной, хотя она будет запутанной, если процедура будет передавать множество необязательных параметров. (Хотя это скорее архитектурная проблема.) - person APC; 19.12.2017