PL/SQL存储过程(Oracle)

                   PL/SQL 存储 过程 (O racle)

1. 查询Oracle数据库的所有的系统权限,一般是DBA

Select * from ststem_privilege_map order by name;

2. 查询所有的角色,一般是DBA

Select * from dba_roles;

3. 查询所有对象的权限,一般是DBA

Select distinct privilege from dba_tablespaces;

4. 查询某个用户具有怎样的角色

Select * from dba_role_privs where grantee =’用户名’;

5. 查询,某个角色包括哪些系统权限

Select * from dba_sys_privs where gtantee=”DBA”

或select * from rolr_sys_privs shere role=”DBA”;

 

 

PL/SQL块

Declear(可选)

--申明部分(常量、变量、游标、例外、复杂数据类型结构)

Begin

--执行部分

Ecxoption(可选)

--例外部分

End

 

例:&表示接受控制输入的数

Declear

V_name varchar(2);

V_sal number()7,2;

Begin

Select name,sal into v_name,v_sal from emp where empno=&no;

Dbms_output.put_line(姓名:’||v_name||工资:’||v_sal);

Exception

When no_data_found then

Dbms.output.put_line(‘编号不存在’);

End;

 

过程例子

Create procedure sp_pro1(spName varchar2,newSal number) is

Begin

--根据用户名修改工资

Update emp set set sal=newSal where eName=spName;

End;

 

调用过程

1. exec 过程名(参数);

2. call 过程名(参数);

 

标量定义

1. 定义一个变长字符串

V_name varchar2(100);

2. 定义一个小数,再范围-999.99~+999.99之间

V_sal number(6,2);

3. 定义一个小数并赋初始值为5.4    :=为数据库赋值符号

V_sal2 number(6.2):=5.4

4. 定义一个日期类型

V_time date;

5. 定义一个布尔类型,不能为空,初始值为false

V_valid Boolean not null default false;

 

复合变量(记录类型 emp.eName%type跟数据表字段eName相同类型

Type emp_record_type is record(name emp.eName%type,salYear emp.sal%type,v_job emp.job%type);

--定义一个变量类型为emp_record_type变量

Sp_record emp_record_type;

 

复合变量(PL/SQL表

相当于高级语言中的数组,但须注意:高级语言中数组下不能为负数,而PL/SQL是可以为负数的,并且表元素的下没有限制

Type sp_table_rype is tale of emp.eName%type index by binsry_integer;

Sq_table sp_table_type;

-- index by binsry_integer  下标类型为整数类型

 

参数变量(游标)

 

Declare 

--定义游标类型

Type sp_emp_cursor is refcursor;

--定义游标变量

Test_cursor sp_emp_cursor;

--定义变量

V_name emp.eName%type;

V_Sal emp.sal%type;

Begin

--打开游标

Open test_cursor for select eName,sal from emp

--循环取值

Loop

Fetch test_cursor into v_name,v_sal;

--判断游标是否为空退出

Exit when test_sursor%notfound;

End loop;

--关闭游标

Close test_corsor;

End;

 

 

函数

:输入name,返回年薪

Create function sp_fun1(name varchar2)

Return number is yearSal number(7,2);

Begin

Select sal*12+nvl(comm,0)*12 into yearSal from emp where eName=name;

Return yearSal;

End;

 

调用函数:

--定义一个变量

Var yearSal number;

Call sp_fun1(‘name’) into:yearSal;

打印

 

--包规范(包含过程和函数的说明,但没有实现)

Create package sp_package1 is 

procedure update_sal(name varchar2,newSal number);--一个过程

function getSalYear(name varchar2);--一个函数

end;

--包体(用于实现规范过程和函数

Create package body sp_package is

Procedure update_sal(name varchar2,newSal number)

Is

Begin

Update emp set sal=newSal where eName=name;

End;

Function getSalYear(name varchar2) ruturn number Is yearSal number;

Begin

Select sal*12+nvl(comm,0)*12 into yearSal from emp where eName=name;

Return yearSal;

End;

End;

调用包

Exec sp_package.过程/函数(参数);

 

判断if then

--编写一个过程,可以输入一个雇员的名字,如果该雇员的薪水低于2000,就给该雇员的工资增加20%

Create or replace procedure sp_pro6(spName varchar2)is

--定义

V_sal emp.sal%type;

--执行

Select sale into v_sal from emp where ename=spName;

--判断

Iv_sal<2000 then 

Update emp set sal=sal*1.1 where ename=spName;

End if;

End;

 

调用:exec sp_pro6(‘name’);

 

判断if then else    (不等于<>)

--编写一个过程,可以输入一个雇员的名字,如果该雇员的补助不是0,在原有基础上增加100;如果补助为0就把补助设为200

Create or replace procedure sp_pro6(spName varchar2)is

--定义

V_somm emp.sal%type;

--执行

Select comm into v_comm from emp where ename=spName;

--判断

Iv_comm<>0 then 

Update emp set comm=comm+100 where ename=spName;

Else

Update emp set comm=comm+200 where ename=spName;

End if;

End;

 

判断if then elsif else

--编写一个过程,可以输入一个雇员的编号,如果该雇员的职位是president,就给他的工资增加1000,如果职位是manager给他的工资增加500,其他职位增加200

Cteate procedure sp_pro8(spNo number) is

V_job emp.job%type;

Begin

Select job into v_job from emp where empNo=spNo;

If v_job=’president’ then 

Update emp set sal=sal+1000 where empNo=spNo;

Elsif v_job=’manager’

Update emp set sal=sal+500 where empNo=spNo;

Else update emp set sal=sal+200 where empNo=soNo;

End if;

End;

 

循环 loop … end loop  至少循环一次 (:=赋值符)

--输入用户名,自动添加十个用户

Create procedure sp_pro9(soName varchar2) is

V_num number:=1;

Begin 

Loop

 Insert into users values(v_num,spName);

--判断是否退出

Ecit when v_num=10;

--自增

V_num:=vnum+1;

End loop;

Eng;

 

While循环

Create procedure sp_pro10oName varchar2) is

V_num number:=11;

Begin 

While v_num<=20 loop

 Insert into users values(v_num,spName);

--判断是否退出

Ecit when v_num=10;

--自增

V_num:=vnum+1;

End loop;

Eng;

 

Goto案例(过程)

Declare 

I int :=1;

Begin 

Loop 

Dbms_output.put_line(‘输出i=’||i);

If i=10 then 

Goto end_loop;

End if;

I:=1+1;

End loop;

<<end_loop>>

Dbms_output.put_line(‘循环结束’);

End;

Pl/sql分页过程

--编写过程

--in 表示这是一个输入参数,默认in

--out 表示一个输出参数

--有输入和输出的存储过程

Create procedure sp_pro12(spno in number,spName out varchar2) is

begin

Select ename into spName from book where boolNo=spno;

End;

 

Java调用过程

Try{

加载驱动

Class.forName(“oracle.jdbc.driver.OracleDriver”);

Connection ct =DriverMananger.getConnection(“jdbc:oracle:thin:@localhost:1521”:”daname”:”pws”);

2.创建CallableStatement

CallableStatement cs=ct.prepareCall(“{call sp_name(?,?,?)}”);

3.给?赋值

Cs.setInt(1,10);

Cs.setString(2,”Dolo”);

Cs.setString(3,”sfaasfasd”);

4.执行

Cs.ececute();

Catch(Ecection e)){

 

}finally{

5.关闭

Cs.close();

Ct.close();

}

 

 

 

Java调用过程(带返回值2个)

Try{

加载驱动

Class.forName(“oracle.jdbc.driver.OracleDriver”);

Connection ct =DriverMananger.getConnection(“jdbc:oracle:thin:@localhost:1521”:”daname”:”pws”);

2.创建CallableStatement

CallableStatement cs=ct.prepareCall(“{call sp_name(?,?,?)}”);

3.给?赋值

Cs.setInt(1,10);

Cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);

Cs.registerOutParameter(3,oracle.jdbc.OracleTypes.VARCHAR);

4.执行

Cs.ececute();

5.取出返回

String name=cs.getString(2);

String age=cs.getString(3);

 

System.out.println(name); 

Catch(Ecection e)){

 

}finally{

5.关闭

Cs.close();

Ct.close();

}

 

返回结果集过程

--创建一个包,在该包中定义了一个游标类型

Create package  testpackage as

Type test_cursor is ref cursor;

End testpackage;

 

--2.创建过程

Create procedure sp_pro19(spNo in number,p_cursor out testpackage.test_cursor)

Is

Begin

Open p_cursur for select * from emp where deptno=soNo);

End;

--3.java调用

Java调用过程(带返回值2个)

Try{

加载驱动

Class.forName(“oracle.jdbc.driver.OracleDriver”);

Connection ct =DriverMananger.getConnection(“jdbc:oracle:thin:@localhost:1521”:”daname”:”pws”);

2.创建CallableStatement

CallableStatement cs=ct.prepareCall(“{call sp_pro19(?,?)}”);

3.给?赋值

Cs.setInt(1,10);

Cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);

4.执行

Cs.ececute();

5.取出结果集

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

While(rs.next()){

System.out.println(rs.getInt(1)+” ”+rs.getString(2)); 

}

Catch(Ecection e)){

 

}finally{

5.关闭

Cs.close();

Ct.close();

}

 

分页存储过程

--oracle分页

Select rownum from 

Select t1.*rownum rn from (Select * from emp)t1 where rn<=10here rn>=5;

 

 

--分页过程

--1.开发一个包

Create package  testpackage as

Type test_cursor is ref cursor;

End testpackage;

 

--2. 创建过程

Create produre fenye

(tableName in varchar2,

pageSize in number,--每页记录数

pageNow in number,

myrows out number,--总记录数

myPafeConunt out number,--总页数

p_cursor out tespackage.test_cursor—返回的记录集合

)

is

--定义sql语句 

V_sql varchar(1000);

--义两个整数

V_begin number:=( pageNow-1)* pagedize+1

V_end number:= pageNow* pagedize

Begin

Select rownum from 

V_sql=:’Select t1.*rownum rn from (Select * from ‘|| tabaleName ||’)t1 where rn<=’||V_end||’here rn>=’|| V_begin ;

--打开游标

Open p_cursor for v_sql;

--计算myrows和myPageCount

V_sql=:’Select count(*) from ‘|| tabaleName;

--执行sql,并把返回的值,赋给myrows

Execute immediate v_sql intp myrows;

--计算myPageCount   mod取余

If mod(myrows, myPageCount)=0 then

myPageCount:= myrows/ pagedize;

else

myPageCount:= myrows/ pagedize+1;

end if;

--关闭游标

Close p_cursor;

End;

 

--3.使用Java调用测试分页

Try{

加载驱动

Class.forName(“oracle.jdbc.driver.OracleDriver”);

Connection ct =DriverMananger.getConnection(“jdbc:oracle:thin:@localhost:1521””daname””pws”);

2.创建CallableStatement

CallableStatement cs=ct.prepareCall(“{call fenye(?,?,?,?,?,?)}”);

3.给?赋值

Cs.setString(1,”表名”);

Cs.setInt(2,5);//每页记录

Cs.setInt(3,2);//总页数

 

 

//注册out 总记录数

Cs.registerOutParameter(4,oracle.jdbc.OracleTypes.INTEGER);

//注册out 总页数

Cs.registerOutParameter(5,oracle.jdbc.OracleTypes.INTEGER);

//注册返回的结果集

Cs.registerOutParameter(6,oracle.jdbc.OracleTypes.CURSOR);

4.执行

Cs.ececute();

//取出总记录数/注意:getInt(44,是由该参数的位置决定的

Int rowNum=cs.getInt(4);

Int pageConnt=cs.getInt(5);

 

5.取出结果集

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

While(rs.next()){

// rs.getInt(1) 第一列    rs.getString(2)第二列  int String 对应表中字段

System.out.println(rs.getInt(1)+” ”+rs.getString(2)); 

}

Catch(Ecection e)){

 

}finally{

5.关闭

Cs.close();

Ct.close();

}

 

 

--要排序的话在最内层加order by

 

 

例外

1. 预定义例外(20多个

1. No_data_found(找不到数据)

2. Case_not_found(没有包含可行分支)

3. Cursor_already_open

4. Invalid_cursor(关闭没打开的游标,从没打开的游标取数据)

5. Invalid_number(输出数据有误触发数据异常)

6. Too_many_rows(返回多行)

7. Zero_divide(2/0语句时,触发)

8. Value_erroe(变量长度不足容纳数据)

2. 非预定义例外

1. login_denide(非法用户登录)

2. not_logged_no(用户么没登陆)

3. storage

3. 自定义例外

--更新用户表,如果没有这个用户

a) Create procedure ex_test(spNo number)

is

--定义一个例外

Myex exception

Begin

--更新用户sal

Update emp set sal=sal+1000 where empno=spNo;

--sql%notfound这里表示没有update

--raise myex;触发myex

If sql%notfound then

Taise myex;

End if;

Exection

When myex then

Dbms_out.put_line(‘没有更新任何用户’);

End;

 

 

视图

--创建视图,把emp表的sal<1000雇员映射到视图

Creste view myview as select * from emp where sal<1000;

 

--创建视图,把emp表的sal<1000雇员映射到视图

Creste view myview2 as select emp.empNo,emp.eName,dept.dName from emp,dep where emp.deptno=dept.empNo;

[with read only]只读

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值