Oracle "IN clause" из параметра - PullRequest
3 голосов
/ 08 июля 2011

Я очень незнаком с Oracle и просто пытаюсь заставить это работать. Я посмотрел здесь и здесь , но не знаю, как заставить все это работать. Вот что мне нужно. Мне нужен процесс, который будет принимать строку с разделителями-запятыми в качестве параметра, который я могу использовать в «предложении IN» запроса и возвращать результат курсора. Есть ли способ сделать это в одном, всеобъемлющем процессе? Если нет, какие шаги мне нужно предпринять? Опять же, я прошу прощения за недостаток знаний об Oracle, я просто пытаюсь заставить что-то работать очень быстро.

Спасибо

Вот процедура (p_Scope будет вводом через запятую):

create or replace PROCEDURE CU_SELECTION_ID
(
p_Scope IN varchar2,
p_ResultSet OUT SYS_REFCURSOR
)
is
BEGIN
OPEN p_ResultSet FOR
select
b.addr1,
b.addr2,
b.city,
b.country_code,
a.customer_no,
b.des1,
a.entity,
b.main_phone_no,
b.phone_area_code,
b.status,
b.wb_site_url,
b.zip
from
ar_customer a,
ct_addr b
where b.main_loc_flag = 'Y' and
a.customer_no = b.customer_no and
a.entity = b.cust_entity and
b.stk_loc_no = '3' and 
b.customer_no in (p_Scope);
END;

Ответы [ 4 ]

5 голосов
/ 09 июля 2011

Я верю, что есть «лучший путь», но я не уверен, что это сейчас…

Это должно работать для вас, хотя:

заменить:

b.customer_no in (p_Scope);

с

instr(p_Scope, ','||b.customer_no||',' ) > 0

Это будет искать p_Scope и вернет значение> 0, если b.customer_no появится в списке.

Убедитесь, что первый и последний символ в списке - это запятая (',')

(также, будучи новичком в Oracle, я обнаружил, что Tech Republic очень полезный быстрый ресурс.)

2 голосов
/ 12 ноября 2012

Принимая объявление

create or replace type cvarchar2 as table of varchar2(4000);

запрос

select * from some_table t where some_column in 
('FOO','BAR')

дает тот же результат, что и

select * from some_table t where some_column in 
(select column_value from table(cvarchar2('FOO','BAR')))

Вы можете использовать второй и передать коллекцию PLSQL в табличную функцию,Я делаю это так из Java, где ...table(?) отлично работает.План объяснения кажется не слишком плохим по сравнению с традиционным предложением IN.

Решения, основанные на текстовом поиске с разделителями, могут снизить производительность.

0 голосов
/ 30 декабря 2015

Вы можете использовать его следующим образом:

 SELECT * FROM MATABLE 
 WHERE MT_ID 
    IN (SELECT REGEXP_SUBSTR(MYPARAM,'[^,]+', 1, LEVEL) 
        FROM DUAL 
        CONNECT BY REGEXP_SUBSTR(MYPARAM, '[^,]+', 1, LEVEL) IS NOT NULL))

MYPARAM- '368134,181956'

0 голосов
/ 09 июля 2011

Кстати, вот еще один уродливый способ сделать это.

   PROCEDURE getreport (
      p_affiliates           IN       varchar2,
      p_StartDate            IN       date,
      p_EndDate              IN       date,
      p_ReturnValue         OUT       sys_refcursor
   ) IS
   BEGIN

        DECLARE
           sql_stmt          VARCHAR2(4000);
        BEGIN

          sql_stmt := 'SELECT
            FIRSTNAME,
            LASTNAME,
            ADDRESSLINE,
            SUITE,
            CITY,
            STATE,
            ZIP
        FROM 
            ORDERHEADER head
            INNER JOIN ORDERDETAIL detail 
                on head.ORDERTRACKINGLOGID = detail.ORDERTRACKINGLOGID
            INNER JOIN ORDERTRACKINGDETAIL trackdetail
                on detail.ORDERDETAILID = trackdetail.ORDERDETAILID 
                    AND head.ORDERHEADERID = trackdetail.ORDERHEADERID
            INNER JOIN AFFILIATE aff
                on trackdetail.AFFILIATEID = aff.AFFILIATEID
        WHERE
            aff.AFFILIATEID IN
            (
                select 
                    AFFILIATEID
                from 
                    AFFILIATE
                where
                    AFFILIATEID IN (' || p_affiliates || ')
            )
            AND
            head.CALENDAR_DATE >= TO_DATE( :p_StartDate )
            AND
            head.CALENDAR_DATE <= TO_DATE( :p_EndDate )    
        ORDER BY AFFILIATEID,
                AFFILIATENAME    
    ';

        OPEN p_ReturnValue for sql_stmt USING p_StartDate, p_EndDate;

        END;

    END getreport;
...