2

我使用 Oracle 10g 编写应用程序。

我目前正面临这个问题。我将“文件名”作为 varchar2 类型的参数。

文件名可能包含的示例值是:'TEST || to_char(sysdate, 'DDD')'。

在这个过程中,我想得到这个文件名的值,就像在 TEST147 中一样。当我写:

select filename
into ffilename
from dual;

我得到值 ffilename = TEST || to_char(sysdate, 'DDD') 这很有意义。但是我怎样才能解决这个问题并在字符串值中调用函数呢?

帮助表示赞赏。谢谢。

4

2 回答 2

5

您示例中的字符串值是无效表达式;它应该是:'测试'|| to_char(系统日期,'DDD')

要评估你可以这样做:

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

然后 v_string 将包含“TEST147”。

于 2010-05-27T08:13:57.443 回答
4

动态执行字符串很容易......

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>

编辑

只是为了公平起见,我觉得我应该指出托尼的解决方案同样有效:

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>

事实上,通过避免 DUAL 上的 SELECT 可能会更好。

于 2010-05-27T12:01:43.447 回答