• 转:Oracle怎么处理动态SQL.ref cursor与using 参数的结合使用.来自AskTom.


    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).
    魔兽就是毒瘤,大家千万不要玩。
  • 相关阅读:
    1、vsCode插件开发流程入门
    node中MySQL的安装与使用
    sublime使用插件
    Node.js基础知识梳理
    第5章-11 字典合并 (40分)
    我的考研心得-zju-se
    解决 重启tomcat上传的文件被自动删除或未重启过段时间也自动删除(deloy path)
    org.hibernate.InstantiationException: No default constructor for entity
    UE.delEditor is not a function问题原因及解决方法
    javaweb开发过程中遇到的问题
  • 原文地址:https://www.cnblogs.com/tracy/p/1722723.html
Copyright © 2020-2023  润新知