2

我在 Oracle 中有一个存储过程,如下所示:

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,但不知道如何使用它。

4

3 回答 3

5

一种方法是使用 aVARRAY作为PARAM_THAT_WILL_BE _USED_INSIDE_WHERE_IN 参数并按照此处
所述使用它 ,但我不确定如何从 c# 调用它。

另一种方法是使用 varchar2 和 csv,如您在问题中所述,但没有动态 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;
于 2012-11-27T09:04:02.293 回答
2

您可以将此逗号分隔的输入参数添加为 varchar() 并使用以下 where 语句:

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)。

于 2012-11-27T09:18:12.623 回答
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(')。例如:'512,456,4564' 如果它有一个值 '512' 像这样

于 2015-12-30T08:28:34.917 回答