2016-04-12 6 views
0

Ich habe folgende Oracle gespeicherte Prozedur, die auf einer Reihe von CSV-Datei, die Benutzer-IDs nimmt die Liste der Benutzer mit dem Ausgang Cursor, der gut arbeitet zurückkehren würde: gespeicherte Prozedur Parameter von CSV-Eingang alle Datensätze zurück

create or replace PROCEDURE GET_USERS_BY_IDS 
(
    v_cur OUT sys_refcursor 
    ,v_userIdsCsv IN varchar2 DEFAULT '' 
) AS 
BEGIN 
open v_cur for 
with userIds 
as 
(
select 
    trim(substr (txt, 
     instr (txt, ',', 1, level ) + 1, 
     instr (txt, ',', 1, level+1) - instr (txt, ',', 1, level) -1)) 
    as token 
    from (select ','||v_userIdsCsv||',' txt 
      from dual) 
    connect by level <= 
    length(v_userIdsCsv)-length(replace(v_userIdsCsv,',',''))+1 
) 
    select 
    id 
    ,lastname 
    ,firstname 
    from 
     users 
    where 
     id in (select * from userIds); 
END GET_USERS_BY_IDS; 

so durch exec GET_USERS_BY_IDS(:cur1, '123,456') kann ich Benutzer von IDs von 123 und 456 erhalten. Allerdings möchte ich ALLE Benutzer zurückgeben, wenn ich eine leere Zeichenfolge übergeben, dh exec GET_USERS_BY_IDS(:cur1, '') würde alle Benutzer zurückgeben. Was muss ich im Sprocode ändern, um das zu erreichen? Vielen Dank.

Antwort

0

Ich denke, ich fand einen effizienteren Weg, dies jetzt zu tun. In der where Aussage kann ich nur Kurzschluss es, wenn der Eingabeparameter ist ein Rohling:

where 
    v_userIdsCsv = '' or 
    id in (select * from userIds); 
+0

Ich glaube nicht, dass Sie einen Where-Klausel Test haben können, wo leere Zeichenfolge = leere Zeichenfolge. Nehmen Sie Ihren Standardwert für v_userIdsCsv '1' vor, und machen Sie dann Ihren Where-Klausel-Test für v_userIdsCsv = '1', und es sollte funktionieren. –

+0

Sie haben eine Antwort angenommen, die nicht funktioniert. Wenn v_userIdsCsv eine leere Zeichenfolge ist, erhalten Sie nicht alle Benutzer wie erwartet. Beweis: 'select sysdate from dual where '' = '';'. Dies funktioniert jedoch gemäß meinem obigen Kommentar: 'select sysdate from dual wobei '1' = '1';'. Bitte bearbeiten Sie diesen Beitrag, um eine gültige funktionierende Antwort anzuzeigen, um zukünftige Suchende nicht zu verwirren. –

0

Haben Sie meinen, etwas so einfaches wie

BEGIN 
    if v_userIdsCsv = '' then 
    open v_cur for select id, lastname, firstname from users 
    else (rest of your code) 
    end if; 

?

OK, mit der Bestätigung in den Kommentaren ...

Es scheint, sollten Sie die WHERE-Bedingung am Ende ändern können:

where 
    v_userIdsCsv = '' or id in (select * from userIds); 
+0

Ich kann das sicherlich tun, aber es wäre die Wiederholung des Codes auf der Auswahl ... – Niner

0

äußere Verbindung zwischen Benutzer und benutzerkennungen. Und schlau, wo Bedingung. Hat es geholfen?

with csv as (select '321,333' aa from dual) 

     ,userIds 
    as 
(
select 
    trim(substr (txt, 
     instr (txt, ',', 1, level ) + 1, 
     instr (txt, ',', 1, level+1) - instr (txt, ',', 1, level) -1)) 
    as token 
    from (select ','||(select aa from csv)||',' txt 
      from dual) 
    connect by level <= 
    length((select aa from csv))-length(replace((select aa from csv),',',''))+1 
) 
    select 
    user_id 
    ,username 
    from 
     all_users a 
    left join userIds b on a.user_id = b.token 
    where nvl2((select aa from csv),b.token,a.user_id) = a.user_id 
1

diese Lösung in Betracht REGEXP Funktionen, die ich Dinge fühlen vereinfacht. Ich habe den Test auch aus meinem Kommentar übernommen. Beachten Sie die REGEXP ein NULL-Listenelement behandelt zu:

create or replace PROCEDURE GET_USERS_BY_IDS 
(
    v_cur OUT sys_refcursor 
    ,v_userIdsCsv IN varchar2 DEFAULT '1' 
) AS 
BEGIN 
open v_cur for 
with userIds 
as 
(
    select trim(regexp_substr(v_userIdsCsv, '(.*?)(,|$)', 1, level, NULL, 1)) as token 
    from dual 
    connect by level <= regexp_count(v_userIdsCsv, ',') + 1 
) 
    select 
    id 
    ,lastname 
    ,firstname 
    from 
     users 
    where v_userIdsCsv = '1' -- Empty list returns all users 
    OR id in (select * from userIds); 
END GET_USERS_BY_IDS; 

Seine ungetestet so lassen Sie uns wissen, was passiert, wenn Sie es testen passiert.

Verwandte Themen