oracle 存储过程 sql中in变量问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle 存储过程 sql中in变量问题相关的知识,希望对你有一定的参考价值。

在oracle的存储过程中,传入一个varchar2型变量a(类型集合),a值为"'a1','a2'"查询在表t中满足出现a中类型的记录数,sql如下:
select count(*) into v_count from t where type in(a);
问题是这样执行结果v_count为0,而执行
select count(*) into v_count from t where type in('a1','a2');结果数是正常的,请教应该如何修改?
不要告诉我使用instr函数,这个效率不能接受

我理解楼主的意思是这样的.这个静态使用有问题.
如果就直接这样执行的话,
select count(*) into v_count from t where type in(a);
应该是有问题的.
可以这样尝试一下:
a varchar2(N);
execute immediate \'select count(1) from t where type in(\'||a||\')\' into v_count ;
还要注意传入的变量,引号别弄丢了...
应该是可以的,我没有测试,很久没有动过这些了.
参考技术A 不知道问题所在,你可以在存储过程中间把A给打印出来看一下,看是不是你说的这个值,如果是的话那看看 where type in(a);这里的语句连接是不是有问题,也可以把语句在执行前赋值给个变量打印出来看看~

会不会是VARCHAR2的长度问题?
参考技术B 为什么不分别传入? 看高人解答。

jonahjeff 传入的那个a解析器会当做一个字符串的,而不是多个。

oracle-游标-存储过程-函数-包

一、存储过程
不可以在insert,update,delete中直接使用,可以有return但代表的是退出过程
过程有三种类型:不返回值,可以返回多个值,参数有三种类型,分别如下:
        in:只输入,不返回结果,默认为in
        out:只返回结果,不输入,要想取出输出变量的值必须通过pl/sql块的变量取出
        in  out:可输入,又可返回结果,要想取出输出变量的值必须通过pl/sql块的变量取出
    --语法
    create or replace procedure 名称(a1 in varchar2,a2 out varchar2,a3 in out int)
        as 

        begin

        end;
    --测试in
        create or replace procedure getSex1(p_customerName in varchar2)
        as 
            v_sex varchar2(20);
        begin
            select sex into v_sex from customer where customerName=p_customerName;
            dbms_output.put_line(v_sex);
        end; 
    --测试out
      create or replace procedure getSex2(p_customerName in varchar2,p_sex out varchar2)
        as 
        begin
          select sex into p_sex from customer where customerName like p_customerName;
        exception
          when others then raise_application_error(-20001,‘occur error‘);
        end;
    --测试in out
        create or replace procedure getSex3(p_param1 in out varchar2) 
        as 
        begin
            select sex into p_param1 from customer where customerName=p_param1;
        end;
    --在pl/sql块中执行
        declare
        begin
              getSex1(‘a1‘);
        end;
    
--在pl/sql块中执行
        declare
            p_sex varchar2(20);
        begin
            getSex2(‘a1‘,p_sex);
            dbms_output.put_line(p_sex);
            getSex2(‘a2‘,p_sex);
            dbms_output.put_line(p_sex);
        end;
        
        declare
            p_sex varchar2(20);
        begin
            p_sex:=‘a1‘;
            getSex3(p_sex);
            dbms_output.put_line(p_sex);
            p_sex:=‘a2‘;
            getSex3(p_sex);
            dbms_output.put_line(p_sex);
        end;
二、函数:
        只能返回且必须返回一个结果,可以直接用在insert,update,delele,select中
    可以有多个return;
    语法:
        create or replace function 函数名(p1 varchar2) return varchar2
        as
        begin
        exception
        end;
    实例:根据姓名返回姓别
        create or replace function getSex(p_customerName varchar2) return varchar2
        as
            v_sex customer.sex%type;
        begin
            select sex into v_sex from customer where customerName=p_customerName;
            return v_sex;
        end;
执行函数:
        1、在sql(sqlplus)
            select getSex(customerName),sex from customer;
        2、在pl/sql块中
      declare
                v_sex customer.sex%type;
            begin
                v_sex:=getsex(‘a1‘);
                dbms_output.put_line(v_sex);
            end;

存储过程:
                  1.声明处没有return,可以返回多个值,用输出变量(out,in out)返回
                    return代表退出程序,不返回结果.
                  2.不可以在insert,update,delete,select
                    中直接使用,只能通过exec中用
 函数:
                  1.声明处有return,只可以返回一个值,
                    return代表返回一个值.
                  2.可以在insert,update,delete,select
                    中直接使用.

三、触发器
set serveroutput on;
create or replace trigger teacher_trigger after insert or update or delete on customer for each row 
begin
dbms_output.put_line(‘the table data already has been modified....‘);
end;

四、游标
        declare
                    v_customer customer%rowtype;
                    v_customerName customer.customerName%type;
                    cursor c1(v_customerName varchar2) is select * from customer     where customerName like v_customerName;
              begin
                    v_customerName:=‘&aa‘;
                    open c1(v_customerName);
                    fetch c1 into v_customer;
                    while(c1%found) loop
                        dbms_output.put_line(v_customer.customerName||‘      ‘||v_customer.sex);
                        fetch c1 into v_customer;
                    end loop;
              end;

五、包
包:包中可以有多个方法,包包括包声明与包主体,包声明中声明的方法名,参数名,类型,个数必须与包主体的方法完全一样。
       包声明中声明的变量是全局变量,大家都可以用
       --实现包声明
create or replace package my_p 
as 
    function getReverse(v_name varchar2) return varchar2;
    procedure teacher_modify_column(teacher_id number,column_name varchar2,column_value1 number);
end;

create or replace package body my_p
as
procedure teacher_modify_column(teacher_id number,column_name varchar2,column_value1 number)
      is 
        v_sql varchar2(200);
      begin
        v_sql:=‘update teachers set  ‘||column_name||‘ =  ‘||column_value1||‘   where teachers.teacher_id =  ‘||teacher_id;
        EXECUTE IMMEDIATE v_sql;    
end teacher_modify_column;
 
function getReverse(v_name varchar2) return varchar2
as
v_title varchar2(200);
i int:=1;
j int:=0;
begin
 j:=length(v_name);
 while (j>0) loop
 v_title:= substr(v_name,i,1)||v_title;
 i:=i+1;
 j:=j-1;
 end loop;
return v_title;
end;
end;

      create or replace package MyPackage as
           type c_type is ref cursor;
           function MyReverse(source varchar2) return varchar2;
           procedure splitPage(p_sql varchar2,page int,pageSize int,result out c_type,pageCount out int); 
      end;
       --实现包主体
        create or replace package body MyPackage as
               function MyReverse(source varchar2) return varchar2
               as 
                 i int;
                 j int;
                 result varchar2(2000):=‘‘;
               begin
                 j:=length(source);
                 i:=1;
                 while(i<=j) loop
                   result:=substr(source,i,1)||result;
                   i:=i+1;
                 end loop;
                 return result;
               end;
             // 查询语句           页数                                                 
               procedure splitPage(p_sql varchar2,page int,pageSize int,result out c_type,pageCount out int)
               as 
                 v_sql varchar2(500);
                 startPage int;
                 endPage int;
                 v_rowCount int;
               begin
                 v_sql:=‘select count(*) from (‘||p_sql||‘)‘;
                 dbms_output.put_line(v_sql);
                 execute immediate v_sql into v_rowCount;
                 pageCount:=ceil(v_rowCount/pageSize);
                 if(page=0) then 
                   raise_application_error(-20001,‘申请的页面太小‘);
                 end if;
                 if(page>pageCount) then 
                   raise_application_error(-20001,‘申请的页面太大‘);
                 end if;
                 startPage:=(page-1)*pageSize;
                 endPage:=page*pageSize;
                 v_sql:=‘select * from (‘||p_sql||‘) where rowNum<=‘||to_char(endPage);
                  v_sql:=v_sql||‘ minus ‘; 
                  v_sql:=v_sql||‘select * from (‘||p_sql||‘) where rowNum<=‘||to_char(startPage);
                  dbms_output.put_line(v_sql);
                  open result for v_sql;
              end;
    end;
    --调用包中的方法
        select MyPackage.MyReverse(sex) from customer;
    --在pl/sql块中调用
    declare
      pageCount int;
      c1 mypackage.c_type;
      v_customer customer%rowtype;
    begin
      mypackage.splitPage(‘select * from customer‘,1,2,c1,pageCount);
      dbms_output.put_line(‘总页数是‘||pageCount);
      fetch c1 into v_customer;
      while(c1%found) loop
             dbms_output.put_line(v_customer.customername||‘  ‘||v_customer.sex);
             fetch c1 into v_customer;
      end loop;
      close c1;
      mypackage.splitPage(‘select * from customer‘,2,2,c1,pageCount);
      fetch c1 into v_customer;
      while(c1%found) loop
             dbms_output.put_line(v_customer.customername||‘  ‘||v_customer.sex);
             fetch c1 into v_customer;
      end loop;
      close c1;
      mypackage.splitPage(‘select * from customer‘,3,2,c1,pageCount);
      fetch c1 into v_customer;
      while(c1%found) loop
             dbms_output.put_line(v_customer.customername||‘  ‘||v_customer.sex);
             fetch c1 into v_customer;
      end loop;
      close c1;  
      
      mypackage.splitPage(‘select * from customer‘,4,2,c1,pageCount);
      fetch c1 into v_customer;
      while(c1%found) loop
             dbms_output.put_line(v_customer.customername||‘  ‘||v_customer.sex);
             fetch c1 into v_customer;
      end loop;
      close c1;      
    end;

 

以上是关于oracle 存储过程 sql中in变量问题的主要内容,如果未能解决你的问题,请参考以下文章

SQL存储过程定义的变量赋值问题

java调用oracle存储过程 关于sql里面in函数参数的问题

Oracle————存储过程与函数

Oracle————存储过程与函数

ORACLE存储过程怎么调用?

如何在oracle存储过程中执行动态sql语句