sql >> Database teknologi >  >> RDS >> Oracle

Konverter et stykke SQL til en Oracle-funktion

Den forespørgsel, du forsøger at komme til:

SELECT id, split_function(city) FROM COMMA_SEPERATED

vil ikke virke, fordi du forsøger at returnere flere rækker for hver kilderække. Du skal desværre gøre det lidt mere kompliceret end som så.

Hvis målet er at skjule opdelingsmekanismen, så er det tætteste jeg kan komme i tanke om at oprette en funktion, som returnerer en samling af strenge, som kunne være pipelinet :

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;
/

Dit foreslåede opkald vil så give dig én række pr. ID med en samling:

select id, split_function(city) from comma_seperated;

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

hvilket ikke helt er, hvad du ønsker; men du kan bruge et tabelsamlingsudtryk og cross-join til at konvertere til flere rækker i stedet:

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<>fiddle-demo .

Det er ikke så simpelt, som du håbede på, men det er uden tvivl stadig bedre end at kryds-joining til xmltable() , især hvis du vil genbruge den opdelingslogik/funktion flere steder, samt skjule detaljerne om, hvordan opdelingen udføres - hvilket ville lade dig ændre mekanismen nemt, hvis du ville, f.eks. at bruge et mere almindeligt regulært udtryk til at foretage opdelingen.



  1. ORA-01017 Ugyldigt brugernavn/adgangskode ved tilslutning til 11g database fra 9i klient

  2. Gem JSON-data i MySQL-tabel

  3. PostgreSQL-fejl:Fatal:rollebrugernavn findes ikke

  4. MySQL:Hvordan laver man en hurtigere IP-områdeforespørgsel? GeoIP