2011-07-08 45 views
3
的Oracle「IN子句」

我對Oracle非常不熟悉,只是試圖使其發揮作用。我看過herehere,但不知道如何使它一切正常。這是我需要的。我需要一個將接受以逗號分隔的字符串作爲參數的過程,我可以在查詢的「IN子句」中使用該參數並返回遊標結果。其他方法可以在一個包羅萬象的過程中做到這一點嗎?如果不是,我需要採取哪些不同的步驟?再次,我對我對甲骨文缺乏瞭解感到抱歉,這只是想讓某些事情真正快速地工作。來自參數

感謝

這裏的PROC(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; 
+0

你看着動態SQL? http://download.oracle.com/docs/cd/A97630_01/appdev.920/a96590/adg09dyn.htm –

+0

請顯示您已經嘗試過的內容。 –

+0

這些是預先存在的需要更改的oracle proc。如果可以在沒有重大結構變化的情況下完成,那麼在這一點上更好。要回答你的問題,不,我沒有看過動態SQL ...我不知道該從哪裏開始:)。 – Metallicraft

回答

4

我相信這是一個「更好的方式」,但我不知道它是正確的現在...

這應該爲你工作,但:

取代:

b.customer_no in (p_Scope); 

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

這將搜索p_Scope並返回> 0的值,如果b.customer_no出現在列表中。

確保在列表中第一和最後一個字符是一個逗號(「」)

(也作爲一個新來者到Oracle我發現Tech Republic是一個非常有用的快速資源。)

+0

可能有更「優雅」的方式來做到這一點,但這是非常好的!完美的作品,讓我通過我的駝峯。非常感謝! – Metallicraft

+0

...並感謝您的鏈接! – Metallicraft

+0

方便。投了票。 – Cortright

0

爲了記錄,這裏有另一種醜陋的方式來做到這一點。

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

假設聲明

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

這是對這個問題的推薦方法,但它被忽略。 –

+0

關於這樣的解決方案的細節和陷阱的有趣的文章: http://www.pontis.biz/resources/articles/collection_card.php –

1

你可以用這種方式:

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

如何爲該函數添加一個鏈接到oracle文檔? – rene

+0

你從.net代碼調用? –