web-dev-qa-db-fra.com

Pass (virgule séparé) -Yet Simple Paramètre au curseur

Je dois obtenir une sélection pour une chaîne donnée (avec des valeurs séparées par des virgules) transmises au curseur. Il peut y avoir plusieurs valeurs pouvant être transmises via une variable unique. Mon code est un peu comme:

CURSOR My_Cursor( vsStr1 )
  IS
  SELECT some_field
    FROM some_table
   WHERE txtfield1 IN ( vsStr1 );    --this field is varchar2 type

vsStr1 varchar2(100) := '01, 25, 80, 100';

Comment transmettre cette variable Correclty? Toute aide serait appréciée.

2
Dozent

Le petit truc sale le plus simple que je connaisse pour cela est xmltable(). Avec xmltable() Vous pouvez convertir une liste de valeurs séparées par des virgules en lignes, par exemple:

select * from xmltable('1, 2, 3')

COLUMN_VALUE
------------
1
2
3

Notez comment la colonne est nommée column_value automatiquement. Ceci est une colonne XMLType, que vous devez convertir pour pouvoir le comparer avec vos types habituels, par exemple (column_value).getnumberval() ou alors (column_value).getstringval()

En utilisant maintenant cela, un curseur pourrait être codé comme ceci:

set serveroutput on
declare
  l_parameters varchar2(50) := '101, 102, 103, 104';

  cursor my_cursor (params varchar2)
  is
  select employee_id, first_name, last_name from hr.employees
  where employee_id in
    (select (column_value).getnumberval() from xmltable(params));
begin
  for c in my_cursor(l_parameters) loop
    dbms_output.put_line(c.employee_id || ': ' || c.first_name || ', ' || c.last_name);
  end loop;
end;
/

101: Neena, Kochhar
102: Lex, De Haan
103: Alexander, Hunold
104: Bruce, Ernst
5
Balazs Papp

Voici une solution utilisant l'affacturage sous-requête, les expressions régulières et une requête hiérarchique sur Dual.

CURSOR My_Cursor( vsStr1 ) IS
   WITH 
      RawInputData As (
         SELECT vsStr1 sStr1 FROM dual
         ),
      InputData As (
         SELECT regexp_substr((SELECT sStr1 FROM RawInputData),'[^,]+',1,level) CurrentsStr1 
         FROM dual 
         CONNECT BY level <= length((SELECT sStr1 FROM RawInputData)) 
            - length(replace((SELECT sStr1 FROM RawInputData),',',''))+1
      )  
   SELECT some_field
   FROM some_table
   WHERE txtfield1 IN ( SELECT CurrentsStr1 FROM InputData );

vsStr1 varchar2(100) := '01,25,80,100';
4
Leigh Riffel