我有点腌渍。我有一个存储过程接受一个参数并返回一个查询的结果。该查询使用IN语句。
这是SP的结构:
CREATE OR REPLACE
PROCEDURE EXAMPLE_SP
(
arg VARCHAR2,
argRS1 OUT cursors.rs
)
AS
l_test VARCHAR2(255) := arg;
BEGIN
OPEN argRS1 FOR
SELECT * FROM TABLE1
WHERE LOCATION IN (l_test);
END EXAMPLE_SP;
IN语句中的值的数量可以是可变的。 IN的选项来自UI侧的选定表单复选框。
我正在使用PHP来检索所选的复选框值。我已经尝试将值插入到逗号分隔的字符串中。
我的逻辑是查询看起来像这样:
l_test = 'val1, val2, val3';
SELECT * FROM TABLE1
WHERE LOCATION IN (val1, val2, val3);
但那没用。我不知道该怎么办。提前感谢任何建设性意见或建议。
答案 0 :(得分:0)
您可以将此逗号分隔的输入参数添加为varchar()并使用以下where语句:
where (','||l_test||',' like '%,'||LOCATION||',%')
例如,如果我们得到l_test='2,3,4,5'
和LOCATION=3
:
where (',2,3,4,5,' like '%,3,%')
如果LOCATION值在此列表中,则为TRUE。
答案 1 :(得分:0)
我认为您选择的位置是VARCHAR,因此您需要转换列表,如下所示
l_test = '''val1''||','|| ''val2''||','||''val3''';
这样您的最终查询就像
SELECT * FROM TABLE1
WHERE LOCATION IN ('val1', 'val2', 'val3');
你也可以这样做
CREATE OR REPLACE
PROCEDURE EXAMPLE_SP
(
arg VARCHAR2,
argRS1 OUT cursors.rs
)
AS
l_test VARCHAR2(255) := arg;
BEGIN
l_test:=''''||replace(l_test,',',''',''')||'''';
OPEN argRS1 FOR
SELECT * FROM TABLE1
WHERE LOCATION IN (l_test);
END EXAMPLE_SP;
注意:我没有对此进行测试,但我认为这样你就可以达到你想要的效果
答案 2 :(得分:0)
我会在不使用字符串操作的情况下执行此操作。从理论上讲,SQL注入的风险目前可能很小,因为你使用的是复选框,最好在开始时实施好的练习,所以如果有任何改变,你就不会让自己处于危险之中。
第二个好处是您仍然可以使用列上的任何索引,如果使用like '%...
,则无法使用这些索引。
要执行此操作,您可以使用表格函数和外部对象来填充“输入”列表。
作为示例,我将从USER_OBJECTS返回OBJECT_NAME。
如果我创建两个表:
create table tmp_test ( a number );
create table tmp_test2 ( a number );
和一个用于保存表格列表的对象,或者在您的案例位置。
create type t_test_object is table of varchar2(30);
接下来,这是相当于您的程序。它是一个返回SYS_REFCURSOR的函数。它接受T_TEST_OBJECT作为参数,这意味着首先需要在传递给函数之前填充它。
create or replace function select_many (
Ptest_object in t_test_object
) return sys_refcursor is
l_curs sys_refcursor;
begin
open l_curs for
select object_name
from user_objects
where object_name in ( select *
from table(Ptest_object)
);
return l_curs;
end;
最后,这是一个如何使用此设置的示例。请注意T_TEST_OBJECT的实例如何填充多个值。然后该对象被传递给函数以返回光标。最后,显示值循环光标的值。显然,您可能希望使用光标并以不同方式填充TYPE。
SQL> declare
2
3 l_nested_table t_test_object := new t_test_object();
4 l_cursor sys_refcursor;
5 -- Used for display demonstration only.
6 l_object_name user_objects.object_name%type;
7
8 begin
9
10 l_nested_table.extend;
11 l_nested_table(l_nested_table.last) := 'TMP_TEST';
12 l_nested_table.extend;
13 l_nested_table(l_nested_table.last) := 'TMP_TEST2';
14
15 l_cursor := select_many(l_nested_table);
16
17 loop -- Display example, not really relevant
18 fetch l_cursor into l_object_name;
19 exit when l_cursor%notfound;
20 dbms_output.put_line(l_object_name);
21 end loop;
22
23 end;
24 /
TMP_TEST
TMP_TEST2
PL/SQL procedure successfully completed.
答案 3 :(得分:0)
您可以使用Oracle文档中的Oracle示例:http://docs.oracle.com/cd/B28359_01/win.111/b28378/basfeat.htm#sthref207
看这里 - 返回一张桌子: Can an SQL procedure return a table?
这是另一个例子:
PACKAGE emp_actions IS
TYPE EnameTabTyp IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER;
TYPE SalTabTyp IS TABLE OF emp.sal%TYPE INDEX BY BINARY_INTEGER;
...
PROCEDURE hire_batch (ename_tab IN EnameTabTyp, sal_tab IN SalTabTyp, ...);
PROCEDURE log_names (ename_tab IN EnameTabTyp);
END emp_actions;