`
nikoloss
  • 浏览: 32914 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

oracle过程参数可能为空或多个值的查询(一)

阅读更多
   今天在网上逛笔记本,挑眼花了,好在我的要求比较明确,i3或者i5的处理器,独立显卡,4G以上内存……
品牌:√ 不限
价格:√ 4000-5000
屏幕尺寸:√ 15英寸
等等

    我在勾选了我的需求之后,符合条件的产品就被搜索出来了。然而这些条件并不是必须的,你可以勾选其中几个,也可以不勾选,不勾选的话就是完全查询了。
    于是我在想在oracle存储过程里要怎么解决这个问题呢。
    最容易让人想到的是一个参数一个参数的判断,然后去拼接sql,我非常不喜欢拼接sql这种方式,太繁琐而且容易出错并且效率还很低。不在万不得已的情况下,不要使用拼接sql。那么我们怎么简单高效而优雅的解决这个问题呢。
    巧用COALESCE函数来解决它!
    为了测试,我们简单的创建一张产品表,为了方便就建了一张TEST表吧,四个varchar2字段(CPU_,SCREEN,PRICE,ERA)
PS:由于CPU是oracle的保留字段,所以注意我用的是CPU_。
-----------------------------------------------------
TEST|CPU_ |SCREEN|PRICE| ERA
-----------------------------------------------------
          | i3       | 13         | 3999  | 2011
-----------------------------------------------------
          | i3       | 14         | 4399  | 2012
-----------------------------------------------------
          | i5       | 15         | 5200  | 2011
-----------------------------------------------------
          | i5       | 13         | 5499  | 2012
-----------------------------------------------------
          | i7       | 15         | 6999  | 2012
-----------------------------------------------------
创建包,过程
CREATE OR REPLACE PACKAGE PKG_DEMO IS
--定义游标
  TYPE P_CURSOR IS REF CURSOR;
--过程申明
  PROCEDURE TEST_SELECT(V_VAR1 IN VARCHAR2,
                        V_VAR2 IN VARCHAR2,
                        V_VAR3 IN VARCHAR2,
                        V_VAR4 IN VARCHAR2,
                        CR OUT P_CURSOR);
END PKG_DEMO;
------------------------------
CREATE OR REPLACE PACKAGE BODY PKG_DEMO IS
--创建包体
 PROCEDURE TEST_SELECT(V_VAR1 IN VARCHAR2,
                       V_VAR2 IN VARCHAR2,
                       V_VAR3 IN VARCHAR2,
                       V_VAR4 IN VARCHAR2,
                       CR OUT P_CURSOR)
     AS
     BEGIN
--这样在参数为空的时候查询条件就成了CPU_=CPU_ AND SCREEN=SCREEN......
       OPEN CR FOR 'SELECT * FROM TEST WHERE CPU_=COALESCE(:X,CPU_)
                      AND SCREEN=COALESCE(:X,SCREEN) 
                      AND PRICE=COALESCE(:X,PRICE) 
                      AND ERA=COALESCE(:X,ERA)' 
                      USING 
                      V_VAR1,
                      V_VAR2,
                      V_VAR3,
                      V_VAR4;
     END;
END PKG_DEMO;

嗯,这么一来,是不是就把任务简化了许多?
测试一下它吧。
DECLARE
RC SYS_REFCURSOR;
REC TEST%ROWTYPE;
BEGIN
  PKG_DEMO.TEST_SELECT('i5','15',NULL,'',RC);--在oracle中''和null是一样的。
  LOOP FETCH RC INTO REC;
  EXIT WHEN RC%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE('CPU='||REC.CPU_||
                         ' SCREEN='||REC.SCREEN||
                         ' PRICE='||REC.PRICE||
                         ' ERA='||REC.ERA);
  END LOOP;
END;

这样我们就把i5处理器和15寸屏幕的产品给搜索出来了

CPU=i5 SCREEN=15 PRICE=5200 ERA=2011

总结:很多网上的人也遭遇过此类问题,但是他们通过IF X IS NULL THEN 来拼接sql,不仅要一个一个的判断,而且这种写法效率很低,代码的可读性也非常差,本来一句话的代码,可能要写上好几十行。而且执行效率非常低下。而隐式的绑定变量能够让oracle在share_pool中把这句话缓存起来。下次使用就非常的快了。这是至关重要的,同样查询1000条语句,动态拼接sql所使用的时间要比绑定变量所使用的时间就有可能慢100个数量级。在一个笔记本门户网站上,很多时候,远不止1000个人并发检索自己心仪的笔记本。
好了,可能你也注意到了,有时候一个条件可能被勾选多个值,比如CPU 我即勾选了i3又勾选了i5,这种情况下我们要怎么处理呢?下一篇中我们就来实现它。



分享到:
评论

相关推荐

    Oracle9i的init.ora参数中文说明

    如果为此参数指定了一个值, 则该值将覆盖 make 文件中的默认值。 值范围: C 编译程序的完整路径。 默认值: 无 remote_dependencies_mode: 说明: 用于指定数据库为远程 PL/SQL 存储的过程处理被依赖对象的方式。如果...

    oracle实验报告

    2、 定义一个为修改职工表(emp)中某职工工资的存储过程子程序,职工名作为形参,若该职工名在职工表中查找不到,就在屏幕上提示“查无此人”然后结束子程序的执行;否则若工种为MANAGER的,则工资加$1000;工种为...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一。  拉里•埃里森  就业前景 从就业与择业的...

    oracle数据库经典题目

    在共享服务器模式中,一个服务器进程可以为多个用户进程服务器。 4.说明数据库内存结构中SGA和PGA的组成,以及这两个内存区存放信息的区别。 答案: SGA区由数据缓冲区、共享池、重做日志缓冲区、大型池、JAVA池...

    最全的oracle常用命令大全.txt

     很多时候,一般的ORACLE用户不知道如何有效地利用它。  dictionary 全部数据字典表的名称和解释,它有一个同义词dict dict_column 全部数据字典表里字段名称和解释 如果我们想查询跟索引有关的数据字典时,...

    ORACLE,mysql,sqlserver,sybase数据库装文本软件

    此值为0则it参数不生效。 1.第一行是逗号分隔的包括列类型的列信息,例如NAME VARCHAR2(30),注意,区分大小写 2.第一行是列分隔符分隔的列名(不包括列字段信息),注意,列名区分大小写 -it insert type 1.导入的...

    Oracle事例

    多个字段时,在最后加上 Foreign Key (字段名) REFERENCE 表名(字段) 连带删除选项 (on delete cascade 当指定时,如果父表中的记录被删除,则依赖于父表的记录也被删除 REFERENCE 表名() on delete cascade; 7...

    orcale常用命令

    要想启动或关闭ORACLE系统必须首先切换到ORACLE用户,如下 su - oracle a、启动ORACLE系统 oracle>sqlplus SQL>connect internal SQL>startup SQL>quit b、关闭ORACLE系统 oracle>sqlplus SQL>connect internal ...

    oracle从入门到精通

    4、定义空(NULL)值 ...................................................................................................................9 5、别名 ......................................................

    C#基类库(苏飞版)

    取汉字拼音的首字母,只要你输入一个汉字,或者是多个汉字就会取出相应的道字母,主要是方便查询使用的 复制代码 16.配置文件操作类 ConfigHelper 1.根据Key取Value值 2.根据Key修改Value 3.添加新的Key ,Value...

    mysql数据库my.cnf配置文件

    # 为提高性能,MySQL可以以循环方式将日志文件写到多个文件。推荐设置为3 innodb_max_dirty_pages_pct = 90 # innodb主线程刷新缓存池中的数据,使脏数据比例小于90% innodb_lock_wait_timeout = 120 # InnoDB事务在...

    jpivot学习总结.doc

    propertyPrefix 否 String 是 如果存在该属性,多个 SessionParam 将会被创建,每一个 member 的名字的开始部分将采用该属性的值。 providerClass 否 String 是 如果存在该属性,这个类的实例将会从当前的 ...

    java 面试题 总结

    如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 15、error和exception有什么区别? error 表示恢复不是...

    Oracle从入门到精通

    7. tablespace 表空间:一个或多个数据文件的逻辑组成。 ..... 8. redo log file 重做日志文件............................. 9. control file 控制文件 ................................. 10. parameter file 初始...

    mysql数据库的基本操作语法

    视图就是一个表或多个表的查询结果,它是一张虚拟的表,因为它并不能存储数据。 视图的作用、优点: 限制对数据的访问 让复杂查询变得简单 提供数据的独立性 可以完成对相同数据的不同显示 创建、修改视图 create or...

    超级有影响力霸气的Java面试题大全文档

    如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 18、error和exception有什么区别?  error 表示恢复...

    SQL语法大全

    Source参数可以是一个Command对象名称、一段SQL命令、一个指定的数据表名称或是一个Stored Procedure。假如省略这个参数,系统则采用Recordset对象的Source属性。 ActiveConnection Recordset对象可以通过...

    PL/SQL 基础.doc

    注意:1)有多个BOOLEAN表达式时候 AND(与),OR(或),NOT(非) 2)条件为FALSE与TRUE 相同; 2. 循环语句 1) Loop 循环 Loop ... (循环体) IF boolean_expr(条件) THEN /* 加条件语句,当满足条件时候退出循环*/ ...

Global site tag (gtag.js) - Google Analytics