1
votes

obtention d'avertissement: fonction créée avec des erreurs de compilation

J'obtiens une erreur lors de l'exécution de la fonction suivante.Je me cogne la tête depuis un certain temps maintenant.Je suis nouveau sur oracle donc je ne suis pas en mesure de le corriger.Quelqu'un peut-il m'aider?

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


1 commentaires

Exécutez show errors pour voir les messages d'erreur


3 Réponses :


2
votes

Oracle ne fournit pas de fonction dans plsql pour faire une chaîne inverse.

dbms_output
    1
    21
    12
    321

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;
     /
Résultat:
     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;
     /

db fiddle ici


3 commentaires

"Oracle ne fournit pas de fonction en plsql pour faire une chaîne inverse." mais nous pouvons utiliser la fonction SQL en PL / SQL. Voir ma réponse .


sélectionnez reverse (c) en x à partir de dual, l'instruction suivante est en train d'être exécutée.Pourquoi? pouvez-vous expliquer.


car reverse est une fonction du moteur SQL



1
votes

Juste pour le plaisir, sans PL / SQL, en utilisant un peu d'expressions régulières avec requête hiérarchique:

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>

Ou, réécrit en fonction:

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>


0 commentaires

1
votes

Il n'y a pas de fonction PL / SQL reverse () dans Oracle. Cela ne fonctionne donc pas:

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

Cela renvoie l'erreur PLS-00201 que vous avez obtenue.

Cependant, il existe une fonction SQL non documentée qui nous pouvons utiliser en PL / SQL, mais uniquement en invoquant le moteur SQL:

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

Bien sûr, car reverse () n'est pas documenté, nous pas censé l'utiliser, du moins dans le code de production. Je ne sais pas pourquoi c'est non documenté. Je pense qu'Oracle l'utilise pour les index inversés, alors peut-être qu'il y a une limite sur la taille des chaînes réversibles.

Voici un db fiddle démo.


La performance est un peu pire

Je pense que c'est le coût du passage du moteur PL / SQL au moteur SQL et vice-versa. Il s'agit donc de cas d'utilisation. Si nous écrivons une fonction qui ne sera utilisée qu'en PL / SQL pur, je pense que votre approche est la meilleure. Mais si nous écrivons une fonction à utiliser en SQL, j'envisagerais plutôt d'utiliser Oracle intégré, même s'il n'est pas pris en charge.

Bien que pour être honnête, je ne me souviens pas de la dernière fois que j'ai utilisé une fonction reverse () - d'Oracle ou roulée à la main - dans la vraie vie (par opposition à répondre à des questions dans forums ou questions similaires sur Code Golf :)).


1 commentaires

Merci pour l'indice. Je ne connaissais pas encore la fonction. La performance est un peu pire, même avec des valeurs plus petites. db <> fiddle ici