2012-11-27 59 views
2

我有Oracle中的存儲過程使用,如下所示:發送值的陣列,以Oracle過程中WHERE IN子句

CREATE PROCEDURE MY_TEST_PROC(
    CUR OUT SYS_REFCURSOR, 
    PARAM_THAT_WILL_BE _USED_INSIDE_WHERE_IN 
) 
AS 
BEGIN 
    OPEN CUR FOR 
    SELECT * 
     FROM MY_TABLE 
    WHERE COL1 IN (here I want to put values received from C#) 
END; 

在ASP.NET應用側我有一個選擇元件與多個選項。我想在我的WHERE子句中使用這些列表項。我知道我可以在我的存儲過程中使用VARCHAR2輸入參數,從列表項目中生成逗號分隔的字符串,並將其發送到過程。有兩個問題與打算是這樣的:

  1. 我要讓我的網站容易受到SQL注入
  2. 在我的存儲過程我必須使用EXECUTE(「SELECT ...」)模式,我想避免。

如何將這些列表項發送到存儲過程並在WHERE IN子句中使用它們?我使用ODP.NET並聽說過UDT,但不知道如何使用它。

回答

2

您可以添加這個逗號分隔的輸入參數爲VARCHAR()和使用以下其中聲明:

where (','||PARAM_THAT_WILL_BE||',' like '%,'||COL1||',%') 

例如,如果PARAM_THAT_WILL_BE='2,3,4,5'col1=3我們得到:

where (',2,3,4,5,' like '%,3,%') 

,如果COL1值在此列表中,則爲TRUE。 在這裏,你不使用動態查詢,所以你避免擔心1)和2)。

+0

一個非常聰明的方法。 –

+0

雖然可能會降低性能,但確實是一種智能方法。例如,如果col1上有索引,則可能不會使用 –

+1

這不是一種明智的方法。動態SQL應該始終是最後的手段。它也對基本上是自由文本字段的格式(沒有空格,沒有製表符)施加限制。就像AB所說的那樣,就是表現。 – APC

5

的一種方法是使用VARRAYPARAM_THAT_WILL_BE _USED_INSIDE_WHERE_IN 參數,並把它作爲描述here
我不知道,但是,如何將它從C#調用。

另一種方法是使用CSV使用VARCHAR2,你在你的問題,但沒有動態sql指出,像這樣:

CREATE PROCEDURE MY_TEST_PROC(
    CUR OUT SYS_REFCURSOR, 
    PARAM_THAT_WILL_BE varchar2) 
AS 
BEGIN 
    OPEN CUR FOR 
    SELECT * 
     FROM MY_TABLE 
    WHERE COL1 IN (
     select regexp_substr(PARAM_THAT_WILL_BE, '[^,]+',1,level) p 
      from dual t 
     connect by level <= regexp_count(PARAM_THAT_WILL_BE, ',') + 1 
) 
END; 
1

對於這種情況,我用這樣的

CREATE PROCEDURE MY_TEST_PROC(CUR OUT SYS_REFCURSOR,A in VARCHAR2 ) AS BEGIN OPEN CUR FOR SELECT * FROM MY_TABLE WHERE COL1 IN (SELECT REGEXP_SUBSTR(**A**,'[^,]+', 1, LEVEL) FROM DUAL CONNECT BY REGEXP_SUBSTR(**A**, '[^,]+', 1, LEVEL) IS NOT NULL) END;

A值應包含開放式和封閉式qutoes(')。 EX:'512,456,4564' 如果它是這樣一個值'512'