玩转oracle学习第六天

来源:互联网 发布:mac系统怎么看bilibili 编辑:程序博客网 时间:2024/05/16 17:53


1.上节回顾
2.PL/SQL的介绍
3.PL/SQL的基础


理解oracle的pl/sql概念
掌握PL/SQL编程技术(包括编写过程,函数,触发器,包。。。)

PL/SQL是什么?
PL/SQL(procedural language/sql)是oracle在标准的sql语言的扩展,PL/SQL不仅允许
嵌入sql语言,


数据库:编写存储过程,函数,触发器,使用的是PL/SQL语言,PL/SQL简化了复杂度
增加程序的模块化,减小网络的传输的开销,提高安全性,提高程序的运行效率
1.过程,函数,触发器是PL/SQL编写的
2.过程,函数,触发器是在oracle中
3.PL/SQL是非常强大的数据库过程语言
4.过程,函数可以在java程序中调用

传统的操作数据库的方法是:
java程序sql-》sql(数据库编译)

程序要有灵魂,一个程序员的成长是需要过程的,
PL/SQL不好的地方:
1.移植性不好,只能使用单个数据库,不能用于其他数据库

PL/SQL 用什么编写PL/SQL
PL/SQL开发工具
 PL/SQL是oracle公司提供的一个工具
 编写存储过程,向其中插入记录
 1.创建一个简单的表
 create table mytest(name varchar2(20),passwd varchar2(30));
 
 2.创建存储过程
 create or replace procedure sp_pro1 is
 begin
 --执行部分
 insert into mytest values('何世阳','m123')
 end;
 /
 replace:表示有就会替换
 如何查看错误信息:
 show error;
 
 如何调用存储过程?两种方法
 (1)exec sp_pro1(参数1,参数2,。。。);
 (2)call sp_pro1(参数1,参数2,。。。);
 
 使用PL/SQL developer工具开发PL/SQL的存储过程
 create or replace procedure sp_pro2 is
 begin
 delete from mytest where name='何世阳';
 end;
 
 存储过程现在还没有一个标准,各个数据库有自己的存储过程编写规则
 
 PL/SQL编程使用变量和逻辑控制语句,从而编写很有用的功能模块
 
 简单分类:
           |--过程
           |--函数
 块(编程)     
           |--触发器
           |--包
           
编写规范:
(1)注释
   单行注释 --
   select * from emp where empno=7788;--取得员工信息
   多行注释
   /*...*/来划分
(2)表示符号的命名规范
 1)当定义变量,建议用v_作为前缀
 2)常量,c_作为前缀
 3)游标,_cursor作为后缀
 4)例外,e_作为前缀,例如e_error
 
 块的介绍:
 块(block)是PL/SQL的基本程序单元,编写PL/SQL程序实际就是编写PL/SQL块
 
 块的结构图:
 PL/SQL块由三部分构成:定义部分,执行部分,例外处理部分
 如下所示:
 declear
 /*定义部分-----定义常量,变量,游标,例外,复杂数据类型*/
 begin
 /*执行部分-----要执行的PL/SQL语句和sql语句*/
 exception
 /*例外处理部分---处理运行的各种错误*/
 end;
 
 特别说明:
 定义部分是从delete开始的
 该部分是可选的
 执行部分是从begin开始的
 该部分是必须的
 例外处理部分是从exception开始的
 该部分是可选的
 
 java程序结果
 
 public static void main(String[] args)
 {
   int a = 1;
   try
   {
      a++;
   }
   catch(Exception e)
   {
    
   }
 }
 
 最简单的块:
 set serveroutput on --打开输出过程
 begin
 dbms_output.put_line('hello world');
 end;
 
 以上是输出‘hello world’的块,说明如下:
 dbms_output 是oracle所提供的包(类似java的开发包),该包包含一些过程,
 put_line就是dbms_output包的一个过程
 
 declear
  v_ename varchar2(5);--定义字符串变量
  v_sal   number(7.2);
 begin
  select ename into v_ename,v_sal from emp where empno=&no;
  dbms_output.put_line('雇员名'||v_ename);
 exception
 when no_data_found then
 dbms_output.put_line('朋友,你的编号输入有误!');
 end;
 /
 &表示要接受控制台输入的参数
 
 定义部分,执行部分和例外处理部分
 
 oracle事先预定义了一些例外,例如no_data_found
 
 过程:
    过程用于执行特定的操作,当建立过程时,既可以指定输入参数,也可以指定输出参数,通过在过程中
    使用输入参数,可以将数据传递到执行部分,
    通过使用输出参数,可以将执行部分的数据传递到应用环境,在sqlplus中可以使用create procedure命令来建立过程
    实例如下:
    (1)编写一个过程,可以输入雇员名,新工资,可修改雇员的工资
    (2)调用过程有两种方法:
    (3)在java程序中调用一个存储过程
 create procedure sp_pro3(spName varchar2,newSal number) is
 --定义变量部分
 begin
 --执行部分,根据用户名去修改工资
 update emp set sal=newSal where ename = spName;
 end;
 /
 
 调用以上存储过程:
 exec sp_pro3('scott',4789);
 
 java程序中调用一个存储过程
 //编写一个java application程序测试oracle存储过程的调用
 import java.sql.*;
 1.加载驱动
 Class.forName("oracle.jdbc.driver.OracleDriver");
 2.得到连接
 Connection ct = DriverManager.getConnection("");
 3.创建CallableStatement
 CallableStatement cs = 。。。
 
 ?如何使用过程返回值??
 
 函数:函数和过程本身是一家,函数用于返回特定的数据,当建立函数时,在函数头部必须包含return语句
 
 函数案例:
  案例:输入雇员姓名,返回该雇员的年薪
 create function sp_fun2(spName carchar2) return
 number is yearSal number(7,2);
 begin
 --执行部分
 select sal*12+nvl(comm,0)*12 into yearSal from emp where ename=spName;
 return yearSal;
 end;
 调用
 1)在sqlpls中进行函数调用
 tome number
 call sp_fun2('scott') into:abc;
 print abc
 2)同样我们可以在java程序中调用该函数
 select annual_income('SCOTT') from dual;
 可以通过rs.getInt(1)得到返回的结果
 
 触发器:触发器是指隐含的执行的存储过程。当定义触发器时,必须要指定触发器的事件和触发的操作
 
 
 包:包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成
 创建包(声明):
 create package sp_package is
 procedure update_sal(name varchar2,newsal number);
 function annual_income(name varchar2) return number;
 end;
 /
 
 给包实现包体:
 create or replace package sp_package is
 procedure update_sal(name varchar2,newsal number)
 is
 begin
 update emp set sal=newsal where ename=name;
 end;
 function annual_income(name varchar2)
 return number is
 annual_salary number;
 begin
 select sal*12+nvl(comm,0) into annual_salary from emp
 where ename=name;
 return annual_salary;
 end;
 end;
 /
 
 如何调用包,调用包中的过程和函数,调用的时候,需要在过程和函数面前添加包名
 exec sp_package.update_sal('SCOTT',120);
 
 
 PL/SQL基础 定义并使用变量
 标量(scalar)-常用类型
 在PL/SQL中
 标量定义的案例:
 (1)定义一个变长的字符串
 v_ename varchar2(20)
 
 (2)使用一个变量
 数据赋值:    :=
 declare
 c_tax_rate number(3,2) := 0.03;
 
 v_ename varchar2(5);
 v_sal   number(7,2);
 v_tax_sal number(7,2);
 begin
 --执行
 select ename,sal into v_ename,v_sal from emp where empno = &no;
 --计算所得税
 v_tax_sal := v_sal*c_tax_rate;
 --输出
 dbms_output.put_line(姓名是:'' || v_ename ||'工资是:'||v_sal||'交税:'||v_tax_sal) ;
 end;
 
 标量(scalar)-使用%type类型:
 v_ename emp.ename%type;//表示变量v_ename定义的大小和表emp的字段enamel大小一致
 
 复合变量(composite)介绍:
 用于存放多个值的变量,主要包括:
 类似高级语言的结构体
 type emp_recode_type is recode
 (
 name emp.ename%type,
 salary emp.sal%type,
 title emp.job%type
 );
 //定义了一个PL/SQL记录类型emp_recode_type,类型包含是哪个数据name,salary,title
 sp_recode emp_recode_type;//定义了一个变量sp_recode,它的类型为emp_recode_type
 
 具体编写:
 declare
 type emp_recode_type is record(name emp.ename%type,
 salary emp.sal%type,
 title emp.job%type);
 sp_recode emp_recode_type;
 begin
 select ename,sal,job into sp_record from emp where empno=7788;
 dbms_output.put_line('员工名:' || sp_record.name || '工资是' || sp_record.salary);
 end;
 
 复合类型:
 相当于高级高级语言中的数组,但是需要注意的是在高级语言中数组的下标不能为负数,但是此处是可以为负数的
 
 PL/SQL表实例:
 declare
 --index by binary_integer表示下标是整数,正整数和负整数都可以的
 type sp_table_type is table of emp.ename%type index by binary_integer;
 sp_table sp_table_type;
 begin
 select ename into sp_table(0) from emp where empno=7788;
 dbms_output.put_line('员工名:' || sp_table(0));
 end;
 
 ?如何返回多条数据类型??
 
 复合变量-参照变量
 参照变量是指用于存放数值指针的变量,通过使用参照变量,可以使得应用程序共享相同的对象,从而降低占用的控件,在编写
 PL/SQL程序时,可以使用游标比那辆(ref cursor)和对象类型变量(ref obj_type)两种参照变量类型
 
 参照变量-ref cursor游标变量
 使用游标时,当定义游标时不需要
 
 declare
 --定义游标类型sp_emp_cursor
 type sp_emp_cursor is ref cursor;//定义了一个游标
 --定义游标变量
 test_cursor sp_emp_cursor;
 --定义变量
 v_ename emp.ename%type;
 v_sal emp.sal%type;
 begin
 --执行
 --把test_cursor 和一个 select结合,即test_cursor指向结果集
 open test_cursor for select ename,sal from emp where deptno=&no;
loop
 fetch test_cursor into v_ename,v_sal;
 --判断工资高低,决定是否更新
 
 --判断是否test_cursor为空
 exit when test_cursor%notfound;
 dbms_output.put_line('名字:' || v_name || '工资:' || v_sal);
end loop;
 end;
 
 复合变量-嵌套表
 
 复合变量-复合表

0 0