The*_*nge 5 oracle select plsql
第一:谢谢!
我完成了我的另一个项目和惊喜:现在一切正常:-)感谢一些有用的SO思想家!
所以我在这里继续下一个项目.
我想得到这样的东西:
SELECT * FROM tablename WHERE field1=content AND field2=content2 ...
Run Code Online (Sandbox Code Playgroud)
正如您所注意到的那样,这可能是一个非常长的where子句.tablename是一个不会改变的静态属性.
field1,, field2...(!),内容可以改变.
所以我需要一个选项来在递归函数中在PL/SQL中构建一个SQL语句.我真的不知道要搜索什么,所以我在这里要求链接甚至一个词来搜索..
请不要开始争论是否真的需要递归函数或它的不足之处 - 这不是问题;-)
如果你可以帮我创建像SQL-String这样以后能够成功完成SELECT的东西,这将是非常好的!
我能够通过递归函数并每次创建一个更长的字符串,但我不能从它做一个SQL语句..
哦,还有一件事:我通过xmlType(xmldom.domdocument等)获取字段和内容我可以从xmltype获取字段和内容,例如clob
目标是从 WHERE 子句中的可变数量的过滤器动态地组装语句。我不确定递归在哪里适合这一切,所以我将只使用一个数组来处理参数:
SQL> create type qry_param as object
2 (col_name varchar2(30)
3 , col_value varchar(20))
4 /
Type created.
SQL> create type qry_params as table of qry_param
2 /
Type created.
SQL>
Run Code Online (Sandbox Code Playgroud)
该表被传递给一个函数,该函数循环数组。对于数组中的每个条目,它都会以 <name> = '<value>' 格式将一行附加到 WHERE 子句。也许您需要更复杂的过滤 - 不同的运算符、显式数据类型转换、绑定变量 - 但这是总体思路。
SQL> create or replace function get_emps
2 (p_args in qry_params )
3 return sys_refcursor
4 as
5 stmt varchar2(32767);
6 rc sys_refcursor;
7 begin
8 stmt := ' select * from emp';
9 for i in p_args.first()..p_args.last()
10 loop
11 if i = 1 then
12 stmt := stmt || ' where ';
13 else
14 stmt := stmt || ' and ';
15 end if;
16 stmt := stmt || p_args(i).col_name
17 ||' = '''||p_args(i).col_value||'''';
18 end loop;
19 open rc for stmt;
20 return rc;
21 end get_emps;
22 /
Function created.
SQL>
Run Code Online (Sandbox Code Playgroud)
最后,为了执行此查询,我们需要填充数组类型的局部变量并将结果返回到引用游标。
SQL> var l_rc refcursor
SQL> declare
2 l_args qry_params := qry_params
3 (qry_param('DEPTNO', '50')
4 , qry_param('HIREDATE', '23-MAR-2010'));
5 begin
6 :l_rc := get_emps(l_args);
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> print l_rc
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
8041 FEUERSTEIN PLUMBER 7839 23-MAR-10 4250 50
8040 VERREYNNE PLUMBER 7839 23-MAR-10 4500 50
SQL>
Run Code Online (Sandbox Code Playgroud)
编辑
在问题的最后一段中,OP 表示他们正在使用 XML 来传递标准。这个要求并没有显着改变我最初实现的形式。该循环只需要驱动 XPath 查询而不是数组:
SQL> create or replace function get_emps
2 (p_args in xmltype )
3 return sys_refcursor
4 as
5 stmt varchar2(32767);
6 rc sys_refcursor;
7 begin
8 stmt := ' select * from emp';
9 for i in (select * from xmltable (
10 '/params/param'
11 passing p_args
12 columns
13 position for ordinality
14 , col_name varchar2(30) path '/param/col_name'
15 , col_value varchar2(30) path '/param/col_value'
16 )
17 )
18 loop
19 if i.position = 1 then
20 stmt := stmt || ' where ';
21 else
22 stmt := stmt || ' and ';
23 end if;
24 stmt := stmt || i.col_name
25 ||' = '''||i.col_value||'''';
26 end loop;
27 open rc for stmt;
28 return rc;
29 end get_emps;
30 /
Function created.
SQL>
Run Code Online (Sandbox Code Playgroud)
可以看到,这个版本返回的结果与以前相同......
SQL> var l_rc refcursor
SQL> declare
2 l_args xmltype := xmltype
3 ('<params>
4 <param>
5 <col_name>DEPTNO</col_name>
6 <col_value>50</col_value>
7 </param>
8 <param>
9 <col_name>HIREDATE</col_name>
10 <col_value>23-MAR-2010</col_value>
11 </param>
12 </params>');
13 begin
14 :l_rc := get_emps(l_args);
15 end;
16 /
PL/SQL procedure successfully completed.
SQL> print l_rc
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
8041 FEUERSTEIN PLUMBER 7839 23-MAR-10 4250 50
8040 VERREYNNE PLUMBER 7839 23-MAR-10 4500 50
SQL>
Run Code Online (Sandbox Code Playgroud)
在 PLSQL 中你可以这样做:
declare
l_statement varchar2(32767);
begin
l_statement := 'SELECT * FROM tablename WHERE field1=:a AND field2=:b';
-- you now have you query. Put in the values that you like.
execute immediate l_statement
using 'value1','value2';
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29413 次 |
| 最近记录: |