转:Oracle怎么处理动态SQL.ref cursor与using 参数的结合使用.来自AskTom.
2010-04-28 10:28
555 查看
You Asked
Hi Tom,I have a web application connecting to a Oracle DB.
I have a search screen where user can enter any search criterion and submit the information.
The information is collected and passed to an Oracle Stored Proc. where a dynamic query is formed based on the search citerion passed.
Ex
if user entered emp no then
the dynamic query formed would be
select * from emp where empNo = p_empno;
If the user entered emp no and salary then
the dynamic query formed would be
select * from emp where empNo = p_empno and sal = p_salary;
What we are doing is forming the where predicate string dynamically based on user input and using execute immediate to execute above dynamically formed query.
I know this dynamic query would be inefficient as each query would be unique which means hard parsed which means low efficiency.
Actually my search screen has a lot of fields about 50 different fields.
(1)Since p_empno etc are parameters to stored proc are these turned into bind varaibles even though I am using execute immediate ?
(2)
I did search on the net for any help .
One article said a generic search could be formed like this
select * from emp where ename = NVL(:n,ename) and deptno = NVL(:d,deptno) and empno = NVL(:e,empno);
but would be inefficient as it would always lead to full table scans.
Is this true?
(2) I think using this would be better than above since it uses bind variables.
Form the query string like this
select * from emp where ename = :n and deptno = :d and empno = :e using p_ename,p_deptno, p_empno
and then execute above formed dynamic string using execute immediate.
(3) Would you suggest any better way of doing this generic search.
As always thank you for your valuable time in helping out the newbies.
Thank you a million times.
Regards
and we said...
Basically, you will use a ref cursor, and you will build the query dynamically, the query will resemble:where (1=1 or :COLUMN_NAME1 is null) and ( column_name2 = :COLUMN_NAME2 )
you would use the first form:
(1=1 or :column_name1 is null)
when the user did not supply the input to constrain against column_name1 and the second form:
( column_name2 = :COLUMN_NAME2 )
when then do. The optimizer will see (1=1 or ...) and optimize that away, it will be as it is was never there. But, it will give you a bind place holder.
So, if you had three inputs (c1, c2, c3) you would build a query like:
select ... from ... where (1=1 or :c1 is null) and (c2 = :c2) and (c3 = :c3)
and then:
open C for that_string using p_c1, p_c2, p_c3;
and that would process a query whereby the end user supplied c2 and c3 - but not c1. And it would do it as efficiently as possible - using an index on c2 or c3 or c2+c3 if appropriate (you get the best plan based on the inputs that are provided)
by the way - BOTH of your examples used bind variables. But they are not equivalent (the second one would not return the right answer, and the first one would be slow - a full scan every time).
相关文章推荐
- Oracle里面的using作用(用于动态sql绑定参数)
- Oracle技术之使用REF CURSOR处理Oracle的结果集
- 使用REF CURSOR处理Oracle的结果集
- 使用REF CURSOR处理Oracle的结果集
- Sql Server cursor 的使用处理重复数据 动态拼接 SQL语句
- 转Asktom:Oracle中怎么处理in的动态SQL语句.
- Oracle动态sql返回游标(sys_refcursor)
- oracle 执行动态sql,using动态参数
- Oracle使用PL/SQL脚本给表结构相同的动态表添加字段
- 数据库操作_连接SQL Server数据库示例;连接ACCESS数据库;连接到 Oracle 数据库示例;SqlCommand 执行SQL命令示例;SqlDataReader 读取数据示例;使用DataAdapter填充数据到DataSet;使用DataTable存储数据库表;将数据库数据填充到 XML 文件;10 使用带输入参数的存储过程;11 使用带输入、输出参数的存储过程示;12 获得数据库中表的数目和名称;13 保存图片到SQL Server数据库示例;14 获得插入记录标识号;Exce
- oracle动态sql:存储过程中动态调用存储过程,并且动态调用的存储过程出参数游标
- 使用动态SQL语句是最简单的处理方法。
- oracle pl/sql 入门+ 数组使用+游标+动态SQL
- 使用Oracle的DBMS_SQL包执行动态SQL语句
- oracle动态sql语句处理——47522341的专栏在去dba的路上
- Oracle中替代变量(动态参数)的使用
- oracle动态sql的简单使用
- oracle 动态SQL在存储过程中的使用
- 简单测试动态游标(REF CURSOR)的使用
- 使用Oracle的DBMS_SQL包执行动态SQL语句