Il est assez facile d'exécuter dynamiquement une chaîne ...
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;
/
Le problème se pose lorsque votre chaîne contient littéraux, les citations redoutés ...
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>
Nous devons donc échapper les apostrophes, toutes, y compris celles que vous n'avez pas incluses dans votre chaîne affichée:
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
Juste pour des raisons d'équité, je sens que je dois souligner que la solution de Tony fonctionne tout aussi bien:
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>
En fait, en évitant le SELECT DUAL il est probablement mieux.
L'exécution d'une entrée utilisateur non validée via SQL peut entraîner des attaques par injection SQL. L'utilisation de SELECT fournit au moins une certaine protection car elle limite ce que la fonction peut faire. Permettre l'injection PL/SQL peut conduire à toutes sortes de choses méchantes. –