In和oracle绑定变量机制

 我相信很多的同行应该会有这样的念头:编制一个过程(或者函数),过程中存在一个条件in,对于in的取值希望通过过程的参数来解决,从而达到动态查询的目的。
        典型的,过程可以这样编写:
        create or replace function sp_testamount(p_name in varchar2) return int
        is
            i int;
            vsql varchar2(4000);
        begin 
            execute immediate 'select count(*) into i from testint where name in (:p_name)' ;          
            return i;
        end;
        假设testint.name类型是varchar2,并且假设其中存在数据(共2条记录),分别为:'a'和'b'。
        这个时候,也许你希望这样查询:
        select sp_testamount('a,b') from dual;结果是0.
        或者select sp_testamount('''a'',''b''') from dual,结果依然是0.
        看来完全不是想像中那样的语句select count(*) from testint where nane in ('a','b'),这是因为sql引擎中关于char或者varchar2绑定变量的特殊性所导致的。
       对于字符类型的绑定变量,oracle总是把其当作一个值来看待,无论传入什么样的值,总是当作一个值来处理,所以无论传入'a,b',或者'''aa'',''b''',sql引擎都会做出类似的解释: in ('a,b'),in ('''a'',''b''')。
       因为oracle的sql引擎实在无法辨别你到底是需要传入一个单独的字符串还是用逗号分开的字符串组,只能通通按照一个字符串来处理.
       如果希望达到预期的目的,基本有两种方法可以实现:

      一、使用到动态sql语句.
       vsql:='select count(*) from testint where id in ('||p_name||')';  
       execute immediate vsql into i ; 
       在这种情况下,sql引擎对于传入的没有绑定变量的sql语句就会按照我们预想的那样解释SQL,把IN中的内容合理的分解查询。上面这种方法的一个坏处是,传递参数的时候比较麻烦(举例优先,其它的读者自行考虑)。
       必须申明的是:目前就字符串类型是这样的,而数值类型则不会受到这样的限制
       概因为oracle的sql引擎还不会把逗号之类的符号认做数值的一部分,因为数值oracle的数值输入还是不允许出现逗号的(显示的时候则允许)。

     二、使用instr函数.

     execute immediate 'select count(*) into i from testint where instr(p_name,name ) >0;   
    在这种情况下,利用instr的特性也可以达到效果。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Oracle绑定变量是一种在SQL语句中使用的特殊语法,用于将变量SQL语句中的参数进行绑定。通过使用绑定变量,可以提高SQL语句的执行效率和安全性。 在Oracle中,绑定变量使用冒号(:)作为前缀,并且在SQL语句中使用该变量的地方都需要加上冒号前缀。绑定变量可以在SQL语句执行之前进行赋值,并且可以多次重复使用。 绑定变量的主要优点有: 1. 提高性能:使用绑定变量可以减少SQL语句的解析时间,因为Oracle数据库可以缓存已解析的SQL语句和执行计划,重复使用绑定变量可以直接使用缓存中的执行计划,避免了每次都重新解析SQL语句。 2. 防止SQL注入攻击:通过使用绑定变量,可以将用户输入的数据作为参数传递给SQL语句,而不是将其直接拼接到SQL语句中。这样可以有效防止SQL注入攻击。 3. 简化代码:使用绑定变量可以减少代码量,避免了手动拼接SQL语句的麻烦。 下面是一个使用绑定变量的示例: ```sql DECLARE v_employee_id NUMBER := 100; v_employee_name VARCHAR2(100); BEGIN SELECT employee_name INTO v_employee_name FROM employees WHERE employee_id = :v_employee_id; DBMS_OUTPUT.PUT_LINE('Employee Name: ' || v_employee_name); END; ``` 在上面的示例中,使用了绑定变量:v_employee_id来代替SQL语句中的参数。在执行SQL语句之前,可以将v_employee_id赋值为具体的值,然后执行SQL语句,获取结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值