оракул как конвертировать значение в переменное имя объекта - PullRequest
0 голосов
/ 24 января 2019

извините за мой английский ....

У меня есть имена переменных в таблице.Мне нужно восстановить эти имена для использования со значениями вычисляемых переменных.

    CREATE TABLE S2V_AMG_FLUSSI
(
  COD_COMPAGNIA  VARCHAR2(5 BYTE),
  ID_FLUSSO      INTEGER,
  DS_FLUSSO      VARCHAR2(500 BYTE),
  DS_CONDIZIONE  CLOB
);

Insert into S2V_AMG_FLUSSI
   (COD_COMPAGNIA, ID_FAMIGLIA_FLUSSI, DS_FAMIGLIA_FLUSSI, ID_FLUSSO, DS_FLUSSO, 
    DS_CONDIZIONE)
 Values
   ('32', 41, 'compagnia', 2, 'REVALORIZED', 
    'c_variabile');

declare
c_variabile varchar2(12) := 'aaa';
v_sql clob;
v_campo varchar2(100);
v_valore    varchar2(100);   
begin
    select ds_condizione into v_campo from S2V_AMG_FLUSSI
    where cod_compagnia=32
    and id_flusso=1;

    v_sql:='begin select :v_campo into :v_out from dual; end;' ;
    execute immediate v_sql
    USING v_campo , OUT v_valore;

 dbms_output.put_line(v_valore);
exception
    when others then
        dbms_output.put_line('ERRORE: '||sqlerrm);
end;

ВЫХОД: c_variabile

но я хочу: aaa

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Динамический SQL сложно написать по многим причинам.Одним из них является абстрактная природа кода.Ваше утверждение ...

v_sql:='begin select :v_campo into :v_out from dual; end;' ;

... создает запрос, который возвращает содержимое v_campo.Но вам нужен запрос, который возвращает содержимое переменной, имя которой хранится в v_campo.

Предположим, вы написали следующее:

v_sql:='begin select ' || v_campo ||' into :v_out from dual; end;' ;
execute immediate v_sql
USING  OUT v_valore;

Он отбрасывает, потому что c_variabile является недопустимым идентификатором в объеме запроса.

Это будет работать ...

v_sql:='begin select :'||v_campo||' into :v_out from dual; end;' ;
execute immediate v_sql
USING c_variabile, OUT v_valore;

... но явно бесполезен, потому что он жестко кодирует именно то, что вы хотите мягко.

То, что работает, выглядит так:

declare
    c_variabile varchar2(12) := 'aaa';
    v_sql clob;
    v_campo varchar2(100) := 'c_variabile' ;
    v_valore    varchar2(100);   
begin

    v_sql:='declare '||v_campo||' varchar2(12) := :P1; begin select '|| 
                                            v_campo||' into :v_out from dual; end;' ;
    execute immediate v_sql
    USING 'aaa', OUT v_valore;
    dbms_output.put_line(v_valore);
exception
    when others then
        dbms_output.put_line('ERRORE: '||sqlerrm);
end;

Эторешает проблему, поставленную вашим вопросом, но похоже на обман.И это похоже на обман, потому что это обман: сгенерированный код не использует определенную переменную c_variabile, вместо этого он использует жестко закодированное значение 'aaa'.

Что поднимает соответствующий вопрос, откуда взято значение 'aaa'? .Возможно, вам нужно переосмыслить свой подход, потому что, вероятно, вам нужно решение, которое обрабатывает динамическое получение значений, таких как 'aaa', а также их динамическую обработку.

Как я уже сказал, динамический SQL - сложная задача.

0 голосов
/ 24 января 2019

Просто уберите галочки с имени переменной.

Insert into S2V_AMG_FLUSSI
(COD_COMPAGNIA, ID_FAMIGLIA_FLUSSI, DS_FAMIGLIA_FLUSSI, ID_FLUSSO, DS_FLUSSO, DS_CONDIZIONE)
Values ('32', 41, 'compagnia', 2, 'REVALORIZED', c_variabile);
...