• 转: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).
    魔兽就是毒瘤,大家千万不要玩。
  • 相关阅读:
    log日志框架和LocationAwareLogger问题
    Eclipse 各种小图标的含义
    自定义log4j日志级别
    在Tomcat配置JNDI数据源的三种方式
    mybatis中"#"和"$"的区别
    Postman用法简介-Http请求模拟工具
    mustache模板技术(转)
    VS的编译选项
    Java Service Wrapper简介与使用
    还活着
  • 原文地址:https://www.cnblogs.com/tracy/p/1722723.html
Copyright © 2020-2023  润新知