收到警告:函数创建时出现编译错误

时间:2019-06-26 09:22:13

标签: plsql oracle10g

执行以下功能时出现错误。我已经有一段时间不停地跳动了。我是oracle新手,所以我无法纠正它。有人可以帮忙吗?

create or replace function rever(x int)
return number
is
y varchar2(30);
c varchar2(30);
v int;
begin
y:=to_char(x);
c:=reverse(y);
v:=to_number(c);
return v;
end rever;
/

以下显示为错误消息

LINE/COL ERROR
-------- ----------------------------------------------------------------- 
9/1      PL/SQL: Statement ignored 
9/4      PLS-00201: identifier 'REVERSE' must be declared

3 个答案:

答案 0 :(得分:2)

Oracle没有在plsql中提供函数来反转字符串。

     create or replace function rever(x int)
     return number
     is
       y varchar2(30);
       c varchar2(30);
       v int;
     begin
       y:=to_char(x);

       -- Loop other each char in a string from the last to the first element  
       for i in reverse 1.. length(y)
       loop 
         c:= c|| substr(y,i,1); 
       end loop; 
       v:=to_number(c);
       return v;
     end rever;
     /

测试:

     begin
       dbms_output.put_line(rever(1));
       dbms_output.put_line(rever(12));
       dbms_output.put_line(rever(21));
       dbms_output.put_line(rever(123));
     end;
     /

结果:

dbms_output
    1
    21
    12
    321

db <>提琴here

答案 1 :(得分:1)

出于娱乐目的,在没有PL / SQL的情况下,使用了一些带有层次查询的正则表达式:

SQL> with test (col) as
  2    (select 'Littlefoot' from dual)
  3  select listagg(one, '') within group (order by lvl desc) reversed
  4  from (select level lvl, regexp_substr(col, '.', 1, level) one
  5        from test
  6        connect by level <= length(col)
  7       );

REVERSED
--------------------------------------------------------------------------
toofelttiL

SQL>

或者,将其重写为函数:

SQL> create or replace function f_reverse (par_col in varchar2)
  2    return varchar2
  3  is
  4    retval varchar2(1000);
  5  begin
  6    select listagg(one, '') within group (order by lvl desc)
  7      into retval
  8      from (select level lvl, regexp_substr(par_col, '.', 1, level) one
  9            from dual
 10            connect by level <= length(par_col)
 11           );
 12    return retval;
 13  end;
 14  /

Function created.

SQL> select empno, f_reverse(empno) rev_empno,
  2         ename, f_reverse(ename) rev_ename
  3  from emp
  4  where rownum <= 3;

     EMPNO REV_EMPNO  ENAME      REV_ENAME
---------- ---------- ---------- ----------
      7369 9637       SMITH      HTIMS
      7499 9947       ALLEN      NELLA
      7521 1257       WARD       DRAW

SQL>

答案 2 :(得分:1)

Oracle中没有PL / SQL reverse()函数。所以这行不通:

declare
  v varchar2(20);
begin
  v:= reverse('krow not does ti');
  dbms_output.put_line(v);
end;  
/

它会抛出您得到的PLS-00201错误。

但是,有一个未公开文档的SQL函数,我们可以在PL / SQL中使用它,但是只能通过调用SQL引擎来实现:

declare
  v varchar2(20);
begin
  select reverse('skrow ti') into v from dual;
  dbms_output.put_line(v);
end;  
/

当然,因为reverse()没有记录,所以我们不应该至少在生产代码中使用它。不知道为什么没有记录。我认为Oracle将它用于反向索引,因此在可逆字符串大小上可能存在一些限制。

这是db<>fiddle演示。


  

性能稍差

我认为这是从PL / SQL引擎迁移到SQL引擎再返回的成本。因此归结为用例。如果我们正在编写仅在纯PL / SQL中使用的函数,那么我认为您的方法更好。但是,如果我们正在编写要在SQL中使用的函数,那么我将考虑使用Oracle内置函数,即使它不受支持。

虽然说实话,但我不记得我上次在现实生活中使用reverse()函数(Oracle或手动滚动)(而不是在论坛中回答问题或类似的Code Golf问题:)) 。