PL/SQL编程1-基础

编写第一个存储过程

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;  
原文地址:https://www.cnblogs.com/zydev/p/5304489.html