编写第一个存储过程
create or replace procedure test_pro1 is begin insert into test1 values('01','zydev'); end; /
查看错误
show error
执行存储过程
exec procedure_name(value1,value2); call procedure_name(value1,value2);
编写规范
单行注释 -- 多行注释 /*.......*/ 定义变量 v_name 定义常量 c_name 定义游标 name_cursor 定义例外 e_name
pl/sql块由定义部分(declear),执行部分(begin),例外处理部分(exception)三部分组成
最简单的一个块
SQL> set serveroutput on; --打开输出选项 SQL> begin 2 dbms_output.put_line('hello,world!!!!'); 3 end; 4 /
一个完整的块
declare --定义变量 v_ename varchar2(5); v_sal number(7,2); begin --执行部分,&地址符,表示从控制台接收数据 select ename,sal into v_ename,v_sal from emp where empno=&a; --在控制台显示用户名 dbms_output.put_line('用户名是:'||v_ename||' 工资: '||v_sal); --异常处理 exception when no_data_found then dbms_output.put_line('The input error, please input again!!!'); end;
PL/SQL的复合变量
记录实例
declare type myemp_record_type is record(name myemp.ename%type,sal myemp.sal%type,job myemp.job%type); test_record myemp_record_type; begin select ename,sal,job into test_record from myemp where empno=&no; dbms_output.put_line('姓名:'||test_record.name); end;
表实例,相当于高级语言中的数组
declare type myemp_table_type is table of myemp.ename%type index by binary_integer; test_table myemp_table_type; begin select ename into test_table(0) from myemp where empno=7788; dbms_output.put_line('姓名: '||test_table(0)); end;
参照变量
游标变量 -ref cursor
--输入部门号,显示所有员工工资和姓名 declare --定义一个游标类型 type test_myemp_cursor is ref cursor; --定义一个游标变量 test_cursor test_myemp_cursor; --定义变量 v_name myemp.ename%type; v_sal myemp.sal%type; begin --把游标变量和select结合 open test_cursor for select ename,sal from myemp where deptno=&no; --循环取出 loop fetch test_cursor into v_name,v_sal; exit when test_cursor%notfound; dbms_output.put_line('姓名: '||v_name||' 工资: '||v_sal); end loop; --关闭游标 close test_cursor; end;
存储过程
输入参数
--create producure test_pro3 create or replace procedure test_pro3 (tName varchar2,newSal number) is begin update myemp set sal=newSal where ename=tName; end;
java中调用
//演示Java调用Oracle的存储过程 package com.oracle; import java.sql.*; public class TestOraclePro { public static void main(String agrs[]){ try { //1.加载驱动 Class.forName("oracle.jdbc.driver.OracleDriver"); //2.得到链接 Connection ct=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:mydev","scott","tiger"); //3.创建CallableStatement CallableStatement cs=ct.prepareCall("{call test_pro3(?,?)}"); //4.给问号赋值 cs.setString(1, "SMITH"); cs.setInt(2, 8888); //5.执行 cs.execute(); //6.关闭 cs.close(); ct.close(); } catch(Exception e){ e.printStackTrace(); } } }
条件分支语句
create or replace procedure test_pro6(tName varchar2) is --申明变量 v_job myemp.job%type; --执行 begin select job into v_job from myemp where ename=tName; --判断 if v_job='PRESIDENT' then update myemp set sal=sal+1000 where ename=tName; elsif v_job='MANAGER' then update myemp set comm=comm+500 where ename=tName; else update myemp set comm=comm+200 where ename=tName; end if; end;
循环语句
loop
--循环添加10个用户到user表中,用户编号从一开始增加 create or replace procedure test_pro7(tName varchar2) is --定义 :=表示赋值 v_num number:=1; begin loop insert into users values(v_num,tName); exit when v_num=10; v_num:=v_num+1; end loop; end;
while loop
--增加10个用户,编号从11开始 create procedure test_pro8(tName varchar2) is v_num number:=11; begin while v_num<=20 loop insert into users values(v_num,tName); v_num:=v_num+1; end loop; end;
goto语句
--goto案例,一般开发不建议使用,会破坏程序结构,使其不易维护 declare i int :=1; begin loop dbms_output.put_line('输出i='||i); if i=10 then
--直接跳转到<<end_loop>> goto end_loop; end if; i:=i+1; end loop; dbms_output.put_line('循环结束1'); <<end_loop>> dbms_output.put_line('循环结束2'); end;
函数
--创建函数,输入姓名,返回年薪 create function test_fun1(tName varchar2) return number is
yearSal number(7,2); begin select sal*12+nvl(comm,0)*12 into yearSal from myemp where ename=tName; return yearSal; end;
调用函数方法
var abc number call test_pro1('SCOTT') into:abc
包pck
--创建包,声明改包有一个存储过程和函数 create or replace package test_pck1 is procedure update_sal(name varchar2,newsal number); function annual_income(name varchar2) return number; end;
创建包体
--创建包体 create or replace package body test_pck1 is procedure update_sal(name varchar2,newsal number) is begin update myemp set sal=newsal where ename=name; end; function annual_income(name varchar2) return number is yearSal number; begin select sal*12+nvl(comm,0)*12 into yearSal from myemp where ename=name; return yearSal; end; end;
调用包的过程或函数
call test_pck1.update_sal('SCOTT',120); call test_pck1.annual_income('SCOTT') into:abc
例外处理
常见的预定义例外
1. no_data_found
declare v_name emp.ename%type; begin select ename into v_name from emp where empno=&no; dbms_output.put_line('名字是:'||v_name); exception when no_data_found then dbms_output.put_line('无编号'); end;
2. case_not_found
declare v_sal myemp.sal%type; v_num myemp.empno%type; begin select sal,empno into v_sal,v_num from myemp where empno=&no; case when v_sal<1000 then update myemp set sal=sal+1000 where empno=v_num; when v_sal<2000 then update myemp set sal=sal+500 where empno=v_num; end case; exception when case_not_found then dbms_output.put_line('无匹配项'); end;
自定义例外
create or replace procedure test_pro13(tNo number) is --定义一个例外 myex exception; begin update myemp set sal=sal+100 where empno=tNo; if sql%notfound then raise myex; end if; exception when myex then dbms_output.put_line('没有更新用户'); end;