Reputation: 33
I am getting error while executing the following function.I have been banging my head for quite sometime now.I am new to oracle so I am not able to correct it.Can someone please help?
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;
/
the following is showing as error message
LINE/COL ERROR
-------- -----------------------------------------------------------------
9/1 PL/SQL: Statement ignored
9/4 PLS-00201: identifier 'REVERSE' must be declared
Upvotes: 1
Views: 165
Reputation: 146229
There is no PL/SQL reverse()
function in Oracle. So this does not work:
declare
v varchar2(20);
begin
v:= reverse('krow not does ti');
dbms_output.put_line(v);
end;
/
It throws the PLS-00201 error you got.
However, there is an undocumented SQL function which we can use in PL/SQL, but only by invoking the SQL engine:
declare
v varchar2(20);
begin
select reverse('skrow ti') into v from dual;
dbms_output.put_line(v);
end;
/
Of course, because reverse()
is undocumented we're not supposed to use it, at least in production code. Not sure why it's undocumented. I think Oracle uses it for reverse indexes, so maybe there's some limit on reversible string size.
Here is a db<>fiddle demo.
The performace is a bit worse
I think that is the cost of moving from the PL/SQL engine to the SQL engine and back again. So it comes down to use case. If we're writing a function which will only be used in pure PL/SQL then I think your approach is the better one. But if we're writing a function to be used in SQL then I would consider using the Oracle built-in instead, even though it's not supported.
Although to be honest I can't remember the last time I used a reverse()
function - Oracle's or hand-rolled - in real life (as opposed to answering questions in forums or similar Code Golf questions :) ).
Upvotes: 1
Reputation: 142715
Just for amusement, without PL/SQL, using a little bit of regular expressions with hierarchical query:
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>
Or, rewritten as a function:
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>
Upvotes: 1
Reputation: 3396
Oracle does not provide a function in plsql to do a string reverse.
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;
/
Test:
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;
/
Result:
dbms_output
1
21
12
321
db<>fiddle here
Upvotes: 2