编写一个函数与Oracle数据库中的concat函数的功能相同。

create or replace function myconcat(str in varchar2, str2 in varchar2) return varchar2 is

str_temp varchar2(32767);

begin

  str_temp := str||str2;

  return str_temp;

end myconcat;

 

 

编写一个函数,函数没有参数,该函数返回订单表orders中所有订单总额大于1000元的用户的个数。

 

create or replace function MFun1 return number is

count_temp number;

begin

  select count(*) into count_temp from (select user_id from orders group by user_id having sum(price)>1000);

  return count_temp;

end MFun1;

 

 

根据上一个题,修改这个函数MFun2,这个函数含有一个入参表示钱数,根据这个参数的值来返回订单总额大于这个数的所有用户的个数。

create or replace function mfun2(price_temp in number) return number is

count_temp number;

begin

   select count(*) into count_temp from (select user_id from orders group by user_id having sum(price)>price_temp);

   return count_temp;

end mfun2;

 

 

 

 

存储过程:

有参数,没有返回值,但有out类型的参数(类似于返回值)

 

编写一个存储过程,统计users表中,每种性别的人数输出到控制台上

create or replace procedure sexcount(sex_in in char) is

 

                     num_out number;

 

begin

   if sex_in='m' then

 select count(*) into num_out from users where sex='m';

dbms_output.put_line(num_out);

   else

 select count(*) into num_out from users where sex='f';

 dbms_output.put_line(num_out);

   end if;

end sexcount;

 

编写一个转账的存储过程

create or replace procedure zhuanzhang(id1 in number,id2 in number,money_temp in number,result out varchar2) is

 

   id1_count number;

   id2_count number;

   

   money_id1 number;

 

begin

   

   select count(*) into id1_count from account where id=id1;

   select count(*) into id2_count from account where id=id2;

   

   if(id1_count>0 and id2_count>0) then

   

  select money into money_id1 from account where id=id1;

  

  if(money_id1>=money_temp) then

  

 update account set money=money-money_temp where id=id1;

 update account set money=money+money_temp where id=id2;

 

 commit;

 

 result:='okok';

  

  else

  

 result:='money is not enough';

  

  end if;

  

   else

   

  result:='account is not exist';  

 

   end if;

   

   

   exception

  when others then

result:= 'call admin';

 

end zhuanzhang;

 

Jdbc调用 存储过程:

 

 CallableStatement cs = conn.prepareCall("call zhuanzhang(?,?,?,?)")

 

    cs.setInt(1, id1);

cs.setInt(2, id2);

cs.setInt(3,money);

//-----绑定存储过程汇总前三个in类型的参数

 

//----注册出参(out类型的参数)

cs.registerOutParameter(4, Types.VARCHAR);

 

cs.executeUpdate();  // 先执行

 

result = (String)cs.getObject(4); // 再获得出参

 

带有查询的存储过程

  使用jdbc处理查询结果

*  查询users表中的所有数据的存储过程

  带有查询结果的存储过程,要想拿到存储过程的查询结果,要使用游标!!!

 *****而游标,不能在  声明和begin之间去定义!!!*****

  create or replace procedure aaa(...) is

    ---  不能在此处声明游标

  begin

  End

 

那么如何定义一个游标类型???

  可以使用package(包)

如何使用package???

  package 分成两个部分   头部   身体

     * 在包的头部,定义游标类型和存储过程:

create or replace package zrgk_pkg is

              TYPE users_cur IS REF CURSOR; --定义游标变量用于返回记录集

               procedure findalluser(v_user out users_cur);

          end zrgk_pkg;

 

  

  * 在包的身体部分去实现这个存储过程

  create or replace package body zrgk_pkg is

          procedure findalluser(v_user out users_cur) is

           v_sql varchar2(32767);

       begin

              v_sql:='select * from users';

              open v_user for v_sql; --为查询打开游标(这个游标就指向了这个sql语句的查询结果)

              end findalluser;   

      end zrgk_pkg;

 

 

 不使用package 同样可以完成 使用游标指向查询结果的存储过程!!!

 create or replace procedure findalluser2(v_user out sys_refcursor) is

           v_sql varchar2(20000);

begin

  v_sql:='select * from users';

  open v_user  for v_sql;  

end findalluser2;

jdbc:

cs = conn.prepareCall("call findalluser2(?)");

cs.registerOutParameter(1,OracleTypes.CURSOR);

cs.execute();

rs = (ResultSet)cs.getObject(1);

 

        

相关文章: