sql >> Database >  >> RDS >> Oracle

Converteer een stukje SQL naar een Oracle-functie

De zoekopdracht die u probeert te bereiken:

SELECT id, split_function(city) FROM COMMA_SEPERATED

zal niet werken, omdat u meerdere rijen probeert te retourneren voor elke bronrij. Je moet het helaas wat ingewikkelder maken dan dat.

Als het doel is om het splitsingsmechanisme te verbergen, dan is het beste wat ik kan bedenken het creëren van een functie die een verzameling strings retourneert, wat zou kunnen zijn gepipelined :

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

Uw voorgestelde oproep geeft u dan één rij per ID met een verzameling:

select id, split_function(city) from comma_seperated;

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

wat niet helemaal is wat je wilt; maar u kunt in plaats daarvan een tabelverzamelingsuitdrukking en cross-join gebruiken om naar meerdere rijen te converteren:

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 .

Dat is niet zo eenvoudig als je had gehoopt, maar het is aantoonbaar nog steeds beter dan cross-joining naar de xmltable() , vooral als u die splitsingslogica/functie op meerdere plaatsen wilt hergebruiken, en ook de details wilt verbergen van hoe de splitsing wordt uitgevoerd - waardoor u het mechanisme gemakkelijk kunt wijzigen als u dat wilt, b.v. om een ​​meer algemene reguliere expressie te gebruiken om de splitsing uit te voeren.



  1. ANSI 1992 JOIN's en COMMA's mengen in een query

  2. Hoe MySQL-database verbinden met de ReactJS-app?

  3. Reset het root-wachtwoord van MySQL op Windows

  4. Hoe tel je in Redshift/Postgres rijen die aan een voorwaarde voldoen?