您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息

Oracle 存储过程学习

2024/4/17 18:25:36发布7次查看
oracle 存储过程 学习 目录 oracle 存储过程 1 oracle 存储过程基础知识 1 oracle 存储过程的基本语法 2 关于 oracle 存储过程的若干问题备忘 4 1. 在 oracle 中,数据表别名不能加 as 。 4 2. 在存储过程中, select 某一字段时,后面必须紧跟 into ,如果
oracle存储过程学习
目录
oracle存储过程 1
oracle存储过程基础知识 1
oracle存储过程的基本语法 2
关于oracle存储过程的若干问题备忘 4
1.在oracle中,数据表别名不能加as。 4
2.在存储过程中,select某一字段时,后面必须紧跟into,如果select整个记录,利用游标的话就另当别论了。 5
3.在利用select...into...语法时,必须先确保数据库中有该条记录,否则会报出no data found异常。 5
4.在存储过程中,别名不能和字段名称相同,否则虽然编译可以通过,但在运行阶段会报错 5
5.在存储过程中,关于出现null的问题 5
6.hibernate调用oracle存储过程 6
用java调用oracle存储过程总结 6
一、无返回值的存储过程 6
二、有返回值的存储过程(非列表) 8
三、返回列表 9
在存储过程中做简单动态查询 11
一、本地动态sql 12
二、使用dbms_sql包 13
oracle存储过程调用java方法 16
oracle高效分页存储过程实例 17
oracle存储过程基础知识
商业规则和业务逻辑可以通过程序存储在oracle中,这个程序就是存储过程。
存储过程是sql, pl/sql, java语句的组合,它使你能将执行商业规则的代码从你的应用程序中移动到数据库。这样的结果就是,代码存储一次但是能够被多个程序使用。
要创建一个过程对象(procedural object),必须有create procedure 系统权限。如果这个过程对象需要被其他的用户schema使用,那么你必须有 create any procedure权限。执行 procedure的时候,可能需要excute权限。或者excute any procedure权限。如果单独赋予权限,如下例所示: 
grant  execute on my_procedure  to jelly
调用一个存储过程的例子:
execute my_procedure( 'one parameter');
存储过程(procedure)和函数(function)的区别。
function有返回值,并且可以直接在query中引用function和或者使用function的返回值。
本质上没有区别,都是pl/sql 程序,都可以有返回值。最根本的区别是: 存储过程是命令,  而函数是表达式的一部分。比如:
select max(name) from
但是不能exec max(name) 如果此时max是函数。
package是function,procedure,variables和sql语句的组合。package允许多个procedure使用同一个变量和游标。
创建procedure的语法:
create [ or replace ] procedure [ schema.]procedure
  [(argument [in | out | in out ] [no copy] datatype
    [, argument [in | out | in out ] [no copy] datatype]...
  )]
[ authid { current_user | definer }]
{ is | as } { pl/sql_subprogram_body |
language { java name 'string' | c [ name, name] library lib_name
}]
sql代码:
create procedure sam.credit (acc_no in number, amount in number) as     
   begin   
      update accounts     
      set balance = balance + amount     
      where account_id = acc_no;     
   end;
可以使用create or replace procedure 语句, 这个语句的用处在于,你之前赋予的execute权限都将被保留。
in, out, in out用来修饰参数。
in表示这个变量必须被调用者赋值然后传入到procedure进行处理。
out表示procedure通过这个变量将值传回给调用者。
in out则是这两种的组合。
authid代表两种权限:
定义者权限(difiner right默认),执行者权限(invoker right)。
定义者权限说明这个procedure中涉及的表,视图等对象所需要的权限只要定义者拥有权限的话就可以访问。
执行者权限则需要调用这个procedure的用户拥有相关表和对象的权限。
oracle存储过程的基本语法
1. 基本结构
create or replace procedure存储过程名字
(
    参数1 in number,
    参数2 in number
) as
变量1 integer :=0;
变量2 date;
begin
end存储过程名字
2. select into statement
将select查询的结果存入到变量中,可以同时将多个列存储多个变量中,必须有一条
  记录,否则抛出异常(如果没有记录抛出no_data_found)
例子:
begin
  select col1,col2 into 变量1,变量2 from typestruct where xxx;
  exception
  when no_data_found then
      xxxx;
  end;
  ...
3. if判断
if v_test=1 then
    begin
       do something
    end;
  end if;
4. while循环
while v_test=1 loop
  begin
 xxxx
  end;
  end loop;
5. 变量赋值
v_test := 123;
6. 用for in使用cursor
...
  is
  cursor cur is select * from xxx;
  begin
 for cur_result in cur loop
  begin
   v_sum :=cur_result.列名1+cur_result.列名2
  end;
 end loop;
  end;
7. 带参数的cursor
cursor c_user(c_id number) is select name from user where typeid=c_id;
  open c_user(变量值);
  loop
 fetch c_user into v_name;
 exit fetch c_user%notfound;
    do something
  end loop;
  close c_user;
8. 用pl/sql developer debug
 连接数据库后建立一个test window
  在窗口输入调用sp的代码,f9开始debug,ctrl+n单步调试
9. pl/sql中执行存储过程
在sql*plus中:
  declare  
      --必要的变量声明,视你的过程而定  
  begin  
      execute   yourprocudure(parameter1,parameter2,...);  
  end  
  /
在sql/plus中调用存储过程,显示结果:  
  sql>set serveoutput on    --打开输出
  sql>var info1 number;     --输出1  
  sql>var info2 number;     --输出2  
  sql>declare  
          var1  varchar2(20);       --输入1  
          var2  varchar2(20);     --输入2  
          var3  varchar2(20);       --输入2  
          begin  
              pro(var1,var2,var3,:info1,:info2);  
          end;  
          /  
  sql>print  info1;  
  sql>print  info2;
注:在execute immediate str语句是sqlplus中动态执行语句,它在执行中会自动提交,类似于dp中forms_ddl语句,在此语句中str是不能换行的,只能通过连接字符||,或着在在换行时加上-连接字符。 
关于oracle存储过程的若干问题备忘
1. 在oracle中,数据表别名不能加as。如:
select a.appname from appinfo a;--正确
select a.appname from appinfo as a;-- 错误
 也许,是怕和oracle中的存储过程中的关键字as冲突的问题吧
2. 在存储过程中,select某一字段时,后面必须紧跟into,如果select整个记录,利用游标的话就另当别论了。 select af.keynode into kn 
from appfoundation af
where af.appid=aid and af.foundationid=fid;   -- 有into,正确编译
select af.keynode 
from appfoundation af 
where af.appid=aid and af.foundationid=fid;-- 没有into,编译报错,提示:compilation   error: pls-00428: an into clause is expected in this select statement
3. 在利用select...into...语法时,必须先确保数据库中有该条记录,否则会报出no data found异常。可以在该语法之前,先利用select count(*) from查看数据库中是否存在该记录,如果存在,再利用select...into...
4. 在存储过程中,别名不能和字段名称相同,否则虽然编译可以通过,但在运行阶段会报错 select keynode into kn from appfoundation where appid=aid and foundationid=fid;
-- 正确运行
select af.keynode into kn from appfoundation af where af.appid=appid and af.foundationid=foundationid;
-- 运行阶段报错,提示:
ora-01422:exact fetch returns more than requested number of rows
5. 在存储过程中,关于出现null的问题假设有一个表a,定义如下:
create table a(
id varchar2(50) primary key not null,
vcount number(8) not null,
bid varchar2(50) not null -- 外键 
);
如果在存储过程中,使用如下语句:
select sum(vcount) into fcount from a where bid='xxxxxx';
如果a表中不存在bid=xxxxxx的记录,则fcount=null(即使fcount定义时设置了默认值,如:fcount number(8):=0依然无效,fcount还是会变成null),这样以后使用fcount时就可能有问题,所以在这里最好先判断一下:
if fcount is null then
    fcount:=0;
end if;
这样就一切ok了。
6. hibernate调用oracle存储过程    this.pnumbermanager.gethibernatetemplate().execute(
            new hibernatecallback() ...{
               public object doinhibernate(session session)
                        throws hibernateexception, sqlexception ...{
                   callablestatement cs = session
                           .connection()
                           .preparecall({call modifyapppnumber_remain(?)});
                   cs.setstring(1, foundationid);
                   cs.execute();
                   return null;
               }
           });
用java调用oracle存储过程总结 
一、 无返回值的存储过程测试表:
-- create table
create table testtb
(
  id   varchar2(30),
  name varchar2(30)
)
tablespace bom
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64k
    minextents 1
    maxextents unlimited
  );
例:存储过程为(当然了,这就先要求要建张表testtb,里面两个字段(i_id,i_name)。
):
create or replace procedure testa(para1 in varchar2, para2 in varchar2) as
begin
  insert into bom.testtb(id, name) values (para1, para2);
end testa;
在java里调用时就用下面的代码:
package com.yiming.procedure.test;
import java.sql.callablestatement;
import java.sql.connection;
import java.sql.drivermanager;
import java.sql.resultset;
import java.sql.sqlexception;
import java.sql.statement;
public class testproceduredemo1 {
public testproceduredemo1() {
}
public static void main(string[] args) {
string driver = oracle.jdbc.driver.oracledriver;
string strurl = jdbc:oracle:thin:@10.20.30.30:1521:vasms;
statement stmt = null;
resultset rs = null;
connection conn = null;
callablestatement proc = null;
try {
class.forname(driver);
conn = drivermanager.getconnection(strurl, bom, bom);
proc = conn.preparecall({ call bom.testa(?,?) });
proc.setstring(1, 100);
proc.setstring(2, testone);
proc.execute();
} catch (sqlexception ex2) {
ex2.printstacktrace();
} catch (exception ex2) {
ex2.printstacktrace();
} finally {
try {
if (rs != null) {
rs.close();
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
}
} catch (sqlexception ex1) {
}
}
}
}
二、 有返回值的存储过程(非列表)例:存储过程为:
create or replace procedure testb(para1 in varchar2, para2 out varchar2) as
begin
  select name into para2 from testtb where id = para1;
end testb;
在java里调用时就用下面的代码:
package com.yiming.procedure.test;
import java.sql.callablestatement;
import java.sql.connection;
import java.sql.drivermanager;
import java.sql.resultset;
import java.sql.sqlexception;
import java.sql.statement;
import java.sql.types;
public class testproceduredemo2 {
public static void main(string[] args) {
string driver = oracle.jdbc.driver.oracledriver;
string strurl = jdbc:oracle:thin:@10.20.30.30:1521:vasms;
statement stmt = null;
resultset rs = null;
connection conn = null;
callablestatement proc = null;
try {
class.forname(driver);
conn = drivermanager.getconnection(strurl, bom, bom);
proc = conn.preparecall({ call bom.testb(?,?) });
proc.setstring(1, 100);
proc.registeroutparameter(2, types.varchar);
proc.execute();
string testprint = proc.getstring(2);
system.out.println(=testprint=is= + testprint);
} catch (sqlexception ex2) {
ex2.printstacktrace();
} catch (exception ex2) {
ex2.printstacktrace();
} finally {
try {
if (rs != null) {
rs.close();
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
}
} catch (sqlexception ex1) {
}
}
}
}
注意,这里的proc.getstring(2)中的数值2并非任意的,而是和存储过程中的out列对应的,如果out是在第一个位置,那就是proc.getstring(1),如果是第三个位置,就是proc.getstring(3),当然也可以同时有多个返回值,那就是再多加几个out参数了。
三、 返回列表由于oracle存储过程没有返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但由于是集合,所以不能用一般的参数,必须要用pagkage了.所以要分两部分,
1. 建一个程序包。如下:
create or replace package testpackage as
  type test_cursor is ref cursor;
end testpackage;
2. 建立存储过程,存储过程为:
create or replace procedure testc(p_cursor out testpackage.test_cursor) is
begin
  open p_cursor for
    select * from bom.testtb;
end testc;
可以看到,它是把游标(可以理解为一个指针),作为一个out 参数来返回值的。
在java里调用时就用下面的代码:
在这里要注意,在执行前一定要先把oracle的驱动包放到class路径里,否则会报错的。
package com.yiming.procedure.test;
import java.sql.callablestatement;
import java.sql.connection;
import java.sql.drivermanager;
import java.sql.resultset;
import java.sql.sqlexception;
import java.sql.statement;
public class testproceduredemo3 {
public static void main(string[] args) {
string driver = oracle.jdbc.driver.oracledriver;
string strurl = jdbc:oracle:thin:@10.20.30.30:1521:vasms;
statement stmt = null;
resultset rs = null;
connection conn = null;
callablestatement proc = null;
try {
class.forname(driver);
conn = drivermanager.getconnection(strurl, bom, bom);
proc = conn.preparecall({ call bom.testc(?) });
proc.registeroutparameter(1, oracle.jdbc.oracletypes.cursor);
proc.execute();
rs = (resultset) proc.getobject(1);
while (rs.next()) {
system.out.println( + rs.getstring(1) + + rs.getstring(2) +
);
}
} catch (sqlexception ex2) {
ex2.printstacktrace();
} catch (exception ex2) {
ex2.printstacktrace();
} finally {
try {
if (rs != null) {
rs.close();
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
}
} catch (sqlexception ex1) {
}
}
}
}
在存储过程中做简单动态查询
在存储过程中做简单动态查询代码 ,例如:
create or replace procedure zxm_sb_gz_get
(p_table in varchar2,
p_name in varchar2,
p_value in varchar2,
outpara out lntxdba.zxm_pag_cs_power.c_type
)
as
begin
declare
wherevalue varchar2(200);
begin
wherevalue:=select * from ||p_table|| where ||p_name||=||p_value;
open outpara for
wherevalue;
end;
end;
 
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录