Вызов функции в строке в процедуре Oracle - PullRequest
2 голосов
/ 27 мая 2010

Я пишу приложение, используя Oracle 10g.

Я сейчас сталкиваюсь с этой проблемой. Я принимаю "имя файла" в качестве параметра типа varchar2.

Пример значения, которое может содержать имя файла: «TEST || to_char (sysdate, 'DDD') '.

В процедуре я хочу получить значение этого имени файла, как в TEST147. Когда я пишу:

select filename
into ffilename
from dual;

Я получаю значение ffilename = TEST || to_char (sysdate, 'DDD') имеет смысл. Но как я могу обойти эту проблему и вызвать функцию в строковом значении?

Помощь оценена. Спасибо.

Ответы [ 2 ]

4 голосов
/ 27 мая 2010

Строковое значение в вашем примере является недопустимым выражением; должно быть: 'ТЕСТ' || to_char (sysdate, 'DDD')

Чтобы оценить, что вы можете сделать это:

execute immediate 'begin :result := ' || filename || '; end;'
  using out v_string;

v_string будет содержать 'TEST147'.

3 голосов
/ 27 мая 2010

Достаточно просто динамически выполнить строку ...

create or replace function fmt_fname (p_dyn_string in varchar2)
    return varchar2
is
    return_value varchar2(128);
begin
    execute immediate 'select '||p_dyn_string||' from dual'
        into return_value;
    return  return_value;
end fmt_fname;
/

Проблема возникает, когда ваша строка содержит литералы с страшными кавычками ...

SQL> select fmt_fname('TEST||to_char(sysdate, 'DDD')') from dual
  2  /
select fmt_fname('TEST||to_char(sysdate, 'DDD')') from dual
                                          *
ERROR at line 1:
ORA-00907: missing right parenthesis


SQL>

Итак, мы должны избежать апострофов, всех из них, включая те, которые вы не включили в опубликованную строку:

SQL> select * from t34
  2  /

        ID FILENAME
---------- ------------------------------
         1 APC001
         2 XYZ213
         3 TEST147


SQL> select * from t34
  2  where filename = fmt_fname('''TEST''||to_char(sysdate, ''DDD'')')
  3  /

        ID FILENAME
---------- ------------------------------
         3 TEST147

SQL>

EDIT

Справедливости ради, я чувствую, что должен отметить, что решение Тони работает так же хорошо:

SQL> create or replace function fmt_fname (p_dyn_string in varchar2)
  2      return varchar2
  3  is
  4      return_value varchar2(128);
  5  begin
  6      execute immediate 'begin :result := ' || p_dyn_string || '; end;'
  7          using out return_value;
  8      return  return_value;
  9  end;
 10  /

Function created.

SQL> select fmt_fname('''TEST''||to_char(sysdate, ''DDD'')') from dual
  2  /

FMT_FNAME('''TEST''||TO_CHAR(SYSDATE,''DDD'')')
--------------------------------------------------------------------------------
TEST147

SQL>

На самом деле, избегая SELECT на DUAL, это, вероятно, лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...