Oracle
 sql >> Base de données >  >> RDS >> Oracle

Convertir un morceau de SQL en une fonction Oracle

La requête à laquelle vous essayez d'accéder :

SELECT id, split_function(city) FROM COMMA_SEPERATED

ne fonctionnera pas, car vous essayez de renvoyer plusieurs lignes pour chaque ligne source. Vous devez le rendre un peu plus compliqué que cela malheureusement.

Si l'objectif est de masquer le mécanisme de fractionnement, le plus proche auquel je puisse penser est de créer une fonction qui renvoie une collection de chaînes, qui pourrait être en pipeline :

create or replace function split_function (p_string varchar2)
return sys.odcivarchar2list pipelined as
begin
  for r in (
    select result
    from xmltable (
      'if (contains($X,",")) then ora:tokenize($X,"\,") else $X'
      passing p_string as x
      columns result varchar2(4000) path '.'
    )
  )
  loop
    pipe row (trim(r.result));
  end loop;
end split_function;
/

Votre proposition d'appel vous donnerait alors une ligne par ID avec une collection :

select id, split_function(city) from comma_seperated;

        ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
         1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
         2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')

ce qui n'est pas tout à fait ce que vous voulez ; mais vous pouvez utiliser une expression de collection de table et une jointure croisée pour convertir en plusieurs lignes :

select cs.id, t.column_value as city
from comma_seperated cs
cross join table(split_function(cs.city)) t;

        ID CITY                          
---------- ------------------------------
         1 CHENNAI                       
         1 HYDERABAD                     
         1 JABALPUR                      
         2 BHOPAL                        
         2 PUNE                          

db<>démo de violon .

Ce n'est pas aussi simple que vous l'espériez, mais c'est sans doute encore mieux que la jonction croisée avec le xmltable() , en particulier si vous souhaitez réutiliser cette logique/fonction de division à plusieurs endroits, ainsi que masquer les détails de la façon dont la division est effectuée - ce qui vous permettrait de modifier facilement le mécanisme si vous le souhaitez, par ex. pour utiliser une expression régulière plus courante pour effectuer le fractionnement.