我想将一组值作为参数传递给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注入。
有什么想法吗?
答案 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):
因此,在vb.net(或其他我想的)中,您将使用以下参数替换XML本身:
通过XMLTYPE(:1)
在这种情况下,这里的:1将是XML文本:
(请记住使用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;