有没有办法将一组值作为参数传递给Oracle SQL语句

时间:2013-12-05 13:17:09

标签: sql oracle parameters set

我想将一组值作为参数传递给Sql语句(在vb.net中)。

就我而言:

允许用户上传一组ID,以检查项目的可用性。我想执行一个语句,通过执行以下操作返回与任何ID匹配的项:

SELECT * FROM MyTable WHERE id IN ('123','456','789')

但是我不能将值('123','456','789')作为参数传递,因为它将被视为原子值 - 整个字符串,即,这将不起作用:

SELECT * FROM MyTable WHERE id IN :param

where :param is ('123','456','789')

我无法连接字符串(如上所示),以避免客户端sql注入。

有什么想法吗?

4 个答案:

答案 0 :(得分:1)

您可以将值作为XML传递,并使用XMLDOM解析它们。

请参阅:here

    DECLARE
       vXML   VARCHAR2 (10000 CHAR) := '<ids><id>1</id><id>2</id><id>3</id></ids>';
    BEGIN
       OPEN :refc FOR
          SELECT c."id"
            FROM XMLTABLE ('/ids/id'
                           PASSING XMLTYPE (vXML)
                           COLUMNS "id" VARCHAR2 (32)) c;
    END;

答案 1 :(得分:1)

从VB.net可以将“关联数组”传递给SQL调用。

在PL / SQL中创建如下类型和过程:

CREATE OR REPLACE TYPE NUMBER_TABLE_TYPE AS TABLE OF NUMBER;

CREATE OR REPLACE PACKAGE My_Package AS
    TYPE NUMBER_ARRAY_TYPE IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
    PROCEDURE My_Procedure(arr IN NUMBER_ARRAY_TYPE);
END My_Package;

CREATE OR REPLACE PACKAGE BODY My_Package AS

PROCEDURE My_Procedure(arr IN NUMBER_ARRAY_TYPE) IS
    nested_table NUMBER_TABLE_TYPE := NUMBER_TABLE_TYPE();
BEGIN
    -- First transform "Associative array" to a "Nested Table"
    FOR i IN arr.FIRST..att.LAST LOOP
        nested_table.EXTEND;
        nested_table(nested_table.LAST) := arr(i);
    END LOOP;   

    SELECT * 
    INTO ... 
    FROM MyTable 
    WHERE ID MEMBER OF nested_table;

END My_Procedure;

END My_Package;

在VB.NET中它看起来像这样:

Sub My_Sub(ByVal idArr As Long())
Dim cmd As OracleCommand
Dim par As OracleParameter
    cmd = New OracleCommand("BEGIN My_Package.My_Procedure(:arr); END;"), con)
    cmd.CommandType = CommandType.Text
    par = cmd.Parameters.Add("arr", OracleDbType.Int64, ParameterDirection.Input)
    par.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    par.Value = idArr
    par.Size = idArr.Length
    cmd.ExecuteNonQuery()
End Sub

查看Oracle文档以获取更多信息:PL/SQL Associative Array Binding

答案 2 :(得分:0)

该问题的解决方案是最终构建一个看起来像这样的SQL语句(对不起图像,但是我无法正确粘贴XML):

enter image description here

因此,在vb.net(或其他我想的)中,您将使用以下参数替换XML本身:

通过XMLTYPE(:1)

在这种情况下,这里的:1将是XML文本:

enter image description here

(请记住使用StringBuilder或任何其他有效的XML字符串生成器来构建XML文本。)

答案 3 :(得分:-1)

为什么不能将它作为一个原子值传递,然后使用Oracle提供的INSTR函数。 例如:

WITH MyTable AS (
SELECT 'abc' ID FROM dual UNION ALL
SELECT 'abcc' ID FROM dual UNION ALL
SELECT 'bbc' ID FROM dual UNION ALL
SELECT 'def' ID FROM dual UNION ALL
SELECT 'abcdef' ID FROM dual)
select * from MyTable where instr('(''abc'', ''def'')', '''' || id || '''') > 0;