zoukankan      html  css  js  c++  java
  • 转: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).
    魔兽就是毒瘤,大家千万不要玩。
  • 相关阅读:
    mysqldump数据库转储
    Docker安装Mysql挂载目录时报错:Entrypoint script for MySQL Server 5.7.31-1debian10 started.
    SpringBoot缓存——基本环境搭建
    SpringBoot使用缓存报错java.lang.IllegalStateException: No cache could be resolved for 'Builder[public com.example.bean.Employee
    springboot集成JPA返回Json报错 com.fasterxml.jackson.databind.exc.InvalidDefinitionException
    HTTP定义的8种请求类型
    centos下使用docker方式安装minio,运行时报错Unable to write to the backend解决
    Spring Boot @PropertySource 加载指定yaml配置文件获取不到配置的解决方法
    npm与cnpm的区别
    MySQL day03
  • 原文地址:https://www.cnblogs.com/tracy/p/1722723.html
Copyright © 2011-2022 走看看