`

Oracle PL/SQL 培训

阅读更多

 PL/SQL  (procedural language/sql) 过程化语言

可以编写 存储过程,函数,包,触发器 等等

-------------------------------------运算符 部分----------------------------------------------

= 比较

:= 赋值

<> 不等于

|| 连字符

-------------------------------------定义与使用变量 部分----------------------------------------------

1、标量类型 scalar

2、复合类型 composite

3、参照类型 reference

4、lob(large object)

 

1、标量类型 scalar

1.1、标量类型 scalar - 常用类型

语法:

变量名 [constant] datatype [not null] [:=default | expr]

变量名:就是变量名

constant:说这是常量,需要初始值,且值以后不能改变,可选项

datatype:数据类型

not null : 指定变量不能为空,可选项

:=  给变量或是常量指定初始值,可选项

default 用于指定初始值 ,可选项

expr:指定初始值的pl/sql表达式,可是文本值、其它变量、函数等

 

例子:

1、定义一个变长字符串

v_name varchar2(10)

2、定义一个小数 范围-9999.99~9999.99

v_sal number(6,2)

3、定义一个小数并给个初始值5.4

v_sal2 number(6,2):=5.4

4、定义一个日期类型的变量

v_hiredate date;

5、定义一个布尔变量,不能为空,初始值为false

v_bl boolean not null default false;

 

1.2、标量类型 scalar - 使用%type类型

指定变量的类型与某个字段的类型相同

语法:

变量名 表名.字段名%type

 

例子:

v_name employees.last_name%type

声明变量 v_name的类型是是  employees表的last_name字段的类型。

 

2、复合类型 composite  介绍

2.1 复合类型-PL/SQL记录类型

set serveroutput on;
declare
  --定义一个pl/sql记录类型emp_record_type
  type emp_record_type is record(
       name employees.last_name%type,
       salary employees.salary%type,
       hire_date employees.hire_date%type
  );
  --定义一个emp_record_type类型的变量v_record
  v_record emp_record_type;
  
begin
  select last_name,salary,hire_date into v_record
  from employees where employee_id=206;
  dbms_output.put_line('姓名:'||v_record.name
       ||' 工资:'||v_record.salary
       ||' 入职日期:'||v_record.hire_date
  );
end;

结果:

姓名:Gietz 工资:5555 入职日期:07-6月 -94
PL/SQL procedure successfully completed

 

 

 

2.2 复合类型-PL/SQL表

相当于高级语言中的数组,下标可以为负数

 

declare
  --定义一个pl/sql表类型table_type,名称随意取
  --table_type类型的变量用于存放employees.last_name%type类型的数据
  type table_type is table of employees.last_name%type
  --数组的下标是整数,可是为负
  index by binary_integer;
  
  --声明一个table_type类型的变量v_table
  v_table table_type;
begin
  select last_name into v_table(0) from employees 
  --如果返回多行,会报错,解决方法见后面的参照类型变量
  where employee_id=206;
  dbms_output.put_line('姓名:'||v_table(0));
end; 

 

2.3 复合类型-嵌套表   用的少,略...

2.4 复合类型-变长数组 用的少,略...

 

 

3、参照类型 reference

参照变量是用于存放数值指针的变量,可以使程序共享相同的对象,最常使用的参照变量类型之一就是 游标变量(ref cursor)

 

3.1、参照类型 reference - cursor游标变量

使用游标时,定义游标时不需要指定相应的select语句,但是当使用游标时(open时),需要指定select语句,这样游标就与一个select语句结合了。

 

--编写一个pl/sql块,输入部门编号,显示本部门所有员工的姓名与工资
declare
  --定义一个游标类型test_cursor_type,它是类型。
  type test_cursor_type is ref cursor;
  
  --定义一个游标变量
  test_cursor test_cursor_type;
  
  --定义一般的变量
  v_name employees.last_name%type;
  v_sal  employees.salary%type;
  
begin
  --把test_cursor游标变量与一个select语句结合起来
  --&no 要输入值给no变量
  open test_cursor for select last_name,salary
  from employees where department_id=&no;
  
  --循环取出
  loop
       fetch test_cursor into v_name,v_sal;
       --判断test_corsor是否为空,为空时退出循环
       exit when test_cursor%notfound;
       dbms_output.put_line('姓名:'||v_name||' 工资:'||v_sal);
  end loop;
  
  --关闭游标
  close test_cursor;
end;

 

------------------程序的三大结构:判断结构、顺序结构、循环结构 ---------------------------

判断结构:

if -- 条件 -- then -- 分支1 -- end if

if -- 条件 -- then -- 分支1 -- else -- 分支2 -- end if

if -- 条件1 -- then -- 分支1 -- elsif -- 条件2 -- then -- 分支2 --else -- 分支3 -- end if

 

循环结构:

loop -- 被循环部分 -- exit when 终止循环的条件; --  end loop  至少执行一次

while -- 条件 -- loop -- 被循环部分 -- end loop    满足条件才执行

 

for i in reverse 1..10 loop

     被循环部分

end loop;

 

顺序结构:

goto meta_name; 跳到meta_name处

<<meta_name>>

 

null;语句 , 什么也不做

 

-------------------------------------存储过程部分----------------------------------------------- 

创建一个过程:

create or replace procedure pro1 is
begin
--单行注释  
/*多行注释*/
insert into t7 values(2,'apple');
commit;
end;
/

 

 

查看错误信息:

show error;

 

 

调用过程:

exec 过程名 (参数值1,参数值2...);

call   过程名 (参数值1,参数值2...);

 

删除过程:

drop procedure 过程名;

 

 

 

块的结构说明:

declear

/*定义部分--常量,变量,游标,复杂数据类型*/

begin

/*执行部分--要执行的PL/SQL语句和SQL语句*/

exception

/*异常处理部分*/

end;

 

 

打开输出选项

  

set serveroutput on   
begin
dbms_output.put_line('hello ,world');
end;
/

 

输出:hello ,world

要打开输出选项才能看到。

 

 

在过程中定义一个变量:

 

声明部分略,直接写了执行部分
declare
  v_ename varchar2(25);--定义字符串变量
  v_sal number(7,2);   --定义一个数值变量
begin
  --从输入框输入变量no,用查询的结果为变量赋值,
  --只适合查出一条结果的情况,查不到结果或查到多条结果都会报错
  select last_name,salary into v_ename,v_sal 
  from employees where employee_id=&no;
  dbms_output.put_line('雇员名:'||v_ename||' 薪水:'||v_sal);
end;
/

  

输入:206
输出:雇员名:Gietz 薪水:8300

 

输入一个不存在编号,结果:

ORA-01403: 未找到数据
ORA-06512: 在 line 7

 

 

在过程中处理异常:

 

声明部分略,直接写了执行部分

declare
  v_ename varchar2(25);--定义字符串变量
  v_sal number(7,2);   --定义一个数值变量
begin
  --从输入框输入变量no,查询的结果为变量赋值, 
  --只适合查出一条结果,若查不到执行时会报no_data_found
  select last_name,salary into v_ename,v_sal 
  from employees where employee_id=&no;
  dbms_output.put_line('雇员名:'||v_ename||' 薪水:'||v_sal);
exception
  when no_data_found then
       dbms_output.put_line('无查询结果!');
end;
/

  

输入一个不存在的编号,结果:
无查询结果!

 

程序走过了异常处理部分代码

 

 

创建一个带参数的过程:(无返回)

create procedure pro2 (vname varchar2,newSal number) is
begin
--根据用户名去修改工资
update employees set salary=newSal where last_name=vname;
commit;
end;
/
 
Procedure created
 
SQL> exec pro2('Gietz',5555);   --调用pro2过程,并传入两个参数
 
PL/SQL procedure successfully completed

在java程序中调用上面的过程: 

//1 加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver"); 

//2 得到连接
Connettion cn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:库名称","用户名","密码");

//3 创建CallableStatement
CallableStatement cs=cn.prepareCall("{call pro2(?,?)}"); 

//4 给问号赋值
cs.setString(1,"Gietz");
cs.setInt(2,5555);
 
//5 执行
cs.execute();
 
//6 关闭
cs.close();
cn.close();

 

 

编写一个有返回值的过程(单行记录):

--有输入与输出的存储过程
--in 表示这是输入变量,如果不写默认是in
--out表示这是输出变量
create or replace procedure pro8
(v_no in number,v_name out varchar2) is
begin
      --通过编号找到姓名
      select last_name into v_name 
      from employees where employee_id=v_no;
end;

在java程序中调用上面的过程: 

//1 加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver"); 

//2 得到连接
Connettion cn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:库名称","用户名","密码");

//3 创建CallableStatement
CallableStatement cs=cn.prepareCall("{call pro8(?,?)}"); 

//4 给问号赋值
cs.setInt(1,206);




//5 说明这是一个返回值,是varchar类型。
cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);
 
//6 执行
cs.execute();



//7 取出返回值
String name=cs.getString(2);
 
//8 关闭
cs.close();
cn.close();

  

 

编写一个有返回值的过程(返回结果集):

--创建一个包
create or replace package test_package as
       type test_cursor is ref cursor;
end ;
--创建一个过程
create or replace procedure pro9(
       departID in number,
       --定义一个游标类型的返回变量
       p_cursor out test_package.test_cursor) 
is
begin
       --把select语句与游标关联起来
       open p_cursor for 
       select * from employees where department_id=departID;
end;

 

在java程序中调用上面的过程: 

//1 加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver"); 

//2 得到连接
Connettion cn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:库名称","用户名","密码");

//3 创建CallableStatement
CallableStatement cs=cn.prepareCall("{call pro9(?,?)}"); 

//4 给问号赋值
cs.setInt(1,10);

//5 说明这是一个返回值,游标类型的。
cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);
 
//6 执行
cs.execute();

//7 取出返回值
ResultSet rs = (ResultSet )cs.getObject(2);
while(rs.next()){
     System.out.println( rs.getInt(1) + " " + rs.getString(2) );
}
 
//8 关闭
cs.close();
cn.close();

  

 

-----------------------------------分页的存储过程 ,过程的高级部分-----------------------------------------

分页的SQL ,取第6-10条记录(两头包含):

select * from (select rownum rn,t1.*  from  employees t1 where rownum <=10) where rn>=6;

 

下面是一个简单的分页,无where条件,无页数越界检查

--创建一个包
create or replace package test_package as
       type test_cursor is ref cursor;
end ;

--创建分页过程
create or replace procedure fenye(
       v_tableName in varchar2,--表名
       v_pageSize in number,--每页显示的记录数
       v_pageNum in number,--当前页码
       v_countRows out number,--总记录数
       v_countPages out number,--总页数
       p_cursor out test_package.test_cursor --返回的结果集
) is
v_sql varchar2(1000);
v_begin number:=(v_pageNum-1) * v_pageSize + 1;
v_end number:=v_pageNum*v_pageSize;
begin
      v_sql:='select * from (select rownum rn,t1.*  from  '||v_tableName||' t1 where rownum <='||v_begin||') where rn>='||v_end;
      --把游标与select语句关联起来
      open p_cursor for v_sql;
      --计算总记录数,总页数
      v_sql:='select count(*) from '||v_tableName;
      execute immediate v_sql into v_countRows; --执行sql
      if mod(v_countRows,v_pageSize)=0 then
         v_countPages:=v_countRows / v_pageSize;
      else
         v_countPages:=v_countRows / v_pageSize + 1;
      end if;
      --关闭游标
      close p_cursor;
end;

 

在java程序中调用上面的过程: 

//1 加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver"); 

//2 得到连接
Connettion cn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:库名称","用户名","密码");

//3 创建CallableStatement
CallableStatement cs=cn.prepareCall("{call fenye(?,?,?,?,?,?)}"); 

//4 给问号赋值
cs.setString(1,'employees');

cs.setInt(2,20);

cs.setInt(3,1);

//5 说明这是一个返回值,游标类型的。
cs.registerOutParameter(4,oracle.jdbc.OracleTypes.INTEGER);
cs.registerOutParameter(5,oracle.jdbc.OracleTypes.INTEGER);
cs.registerOutParameter(6,oracle.jdbc.OracleTypes.CURSOR);
 
//6 执行
cs.execute();

//7 取出返回值
int countRows=cs.getInt(4);//总记录数
int countPages=cs.getInt(5);//总页数
ResultSet rs = (ResultSet )cs.getObject(6);
while(rs.next()){
     System.out.println( rs.getInt(1) + " " + rs.getString(2) );
}
 
//8 关闭
cs.close();
cn.close();

   

-----------------------------------------函数部分-------------------------------------------

创建函数:

SQL> --函数例子
SQL> --输入雇员的姓名,返回该雇员的年薪
SQL> --函数的头,vname是要传入的型参,返回一个number类型的yearSal变量
SQL> create function fun1(vname varchar2) return number
  2  is yearSal number(7,2);
  3  begin
  4  select salary*12 into yearSal from employees where last_name=vname;
  5  return yearSal;--返回结果
  6  end;
  7  / 
  
  Function created

 

 

调用函数:

 

在SQLplus中调用函数:

 

SQL> var income number
SQL> call fun1('Gietz') into:income
  2  /
 
Method called
income
---------
66660

 

 

 

在java程序中调用函数:

select fun1('Gietz') from dual;
可以通过rs.getInt(1)得到返回结果

 

 

----------------------------------包 部分--------------------------------------------------

包用于在逻辑上组合过程和函数,它由包规范声明和包体两部分组成。

包的规范只包含了过程和函数的说明,没有实现。要在包体中实现之前声明的过程与函数。

 

创建一个包规范声明:

SQL> --创建一个包pack1
SQL> --这里只起到声明的作用
SQL> create package pack1 is
  2        procedure  pro2 (vname varchar2,newSal number) ; -- 一个过程的声明
  3        function fun1(vname varchar2) return number;     -- 一个函数的声明
  4  end;
  5  /
 
Package created

 

 

创建一个包体:

SQL> create package body pack1 is
  2  
  3    --实现过程,根据用户名去修改工资
  4    procedure pro2 (vname varchar2,newSal number) is
  5    begin
  6    update employees set salary=newSal where last_name=vname;
  7    commit;
  8    end;
  9  
 10    --实现函数,输入雇员的姓名,返回该雇员的年薪
 11    function fun1(vname varchar2) return number
 12    is yearSal number(7,2);
 13    begin
 14    select salary*12 into yearSal from employees where last_name=vname;
 15    return yearSal;
 16    end;
 17  end;
 18  /
 
Package body created

 

 

如何调用包中的过程与函数:

就是在过程与函数名前带包名。

 

 

------------------------------------触发器 部分------------------------------------------------

触发器是一个隐含的存储过程,一般在insert,update,delete语句执行时触发某个pl/sql块。

 

 

 

 

-------------------------------------异常处理-----------------------------------------------

预定义异常 ,大约有20多个

no_data_found  没有找到数据时抛出

case_no_found  case语句中的when子句没有包含必须的条件分支时抛出

cursor_already_open 重复打开已打开的游标时抛出

dup_val_on_index 在唯一索引的列上插入重复的值时抛出

invaild_cursor 在不合法的游标上操作时会抛出, 如:试图重没有打开游标取数据,或关闭没有打开的游标

invaild_number 无效的数值

too_many_rows 返回的结果是多行,但接收的变量只是单行变量 时抛出

zero_divide  当执行2/0时

value_error 变量的长度不足以容纳实际的数据时招聘

 

其它预定义异常

login_denide 非法登录时抛出

not_logged_on 用户没登录就执行dml操作时抛出

 

自定义异常

略。。。

处理导演的例子

begin

......

exception
  when no_data_found then
       dbms_output.put_line('无查询结果!');

 

end;

------------------------------------------------------------------------------------

 

分享到:
评论

相关推荐

    Oracle PL/SQL程序设计(第5版)(套装上下册)

    《Oracle PL/SQL程序设计(第5版)(套装上下册)》结构清晰,示例丰富,实践性强,适用于Oracle数据库开发人员、Oracle数据库管理员等相关数据库从业人员,也可以作为各大、中专院校相关专业师生的参考用书和相关...

    Oracle PL/SQL实战(待续)

    Oracle PL/SQL是一种强大的编程语言,它结合了SQL的数据处理能力与PL的程序设计特性,是Oracle数据库系统中用于创建存储过程、函数、触发器和包的主要工具。在这个"Oracle PL/SQL实战(待续)"的主题中,我们将深入...

    Oracle PL/SQL程序设计(第5版)(上下册)

    ### Oracle PL/SQL程序设计(第5版)(上下册)知识点概述 #### 一、PL/SQL编程基础 - **PL/SQL简介**:PL/SQL(Procedural Language for SQL)是Oracle数据库的一种内嵌式过程化语言,用于增强SQL的功能。它允许在SQL...

    Oracle PL/SQL实例精解 数据库建立代码

    Oracle PL/SQL是一种强大的编程语言,它结合了SQL的数据库操作能力和PL/SQL的结构化编程特性,使得数据库开发者能够创建复杂的应用程序和数据库逻辑。在"Oracle PL/SQL实例精解 数据库建立代码"中,我们将深入探讨...

    Oracle PL/SQL 实例精解(第4版涵盖Oracle 11g)+源码脚本

    Oracle PL/SQL是一种强大的编程语言,它将关系数据库的强大功能与结构化编程的优点结合在一起,是Oracle数据库系统中不可或缺的一部分。在"Oracle PL/SQL 实例精解(第4版涵盖Oracle 11g)+源码脚本"中,读者可以深入...

    oracle pl/sql从入门到精通 配套源代码

    Oracle PL/SQL是一种强大的编程语言,它结合了SQL(结构化查询语言)的数据库操作功能与PL/SQL的程序设计特性,广泛应用于Oracle数据库的开发和管理。这本书"Oracle PL/SQL从入门到精通"的配套源代码,显然是为了...

    ORACLE PL/SQL从入门到精通

    ORACLE PL/SQL是从入门到精通的专业知识,涵盖了数据库开发与管理的多个方面,包括触发器、过程、函数、软件包、异常处理、游标、循环、分支、变量使用、数据库安装等关键知识点。 触发器是数据库中用来保证数据...

    Oracle PL/SQL实例编程(PL/SQL经典书籍)

    Oracle PL/SQL是一种强大的编程语言,它将数据库管理和应用程序逻辑紧密结合起来,是Oracle数据库系统中的核心组件之一。这本书“Oracle PL/SQL实例编程”显然旨在深入讲解如何利用PL/SQL进行实际开发工作,通过实例...

    oracle pl/sql实例精讲student数据库模式数据和表脚本

    Oracle PL/SQL是一种强大的编程语言,它结合了SQL的数据库操作能力和Procedural Language的编程结构,用于在Oracle数据库环境中创建复杂的应用程序。在"Oracle PL/SQL实例精讲student数据库模式"中,我们将深入探讨...

    Oracle PL/SQL学习官方教材

    Oracle PL/SQL是一种强大的编程语言,它将SQL与过程编程语言的特性相结合,为数据库开发提供了丰富的功能。在Oracle数据库环境中,PL/SQL是开发高效、可靠和可维护的数据库应用程序的关键工具。以下是对"Oracle PL/...

    Oracle PL/SQL专家指南-高级PL/SQL解决方案的设计与开发

    《Oracle PL/SQL专家指南-高级PL/SQL解决方案的设计与开发》是一本深入探讨Oracle数据库中的PL/SQL编程的专业书籍。PL/SQL是Oracle数据库特有的编程语言,它结合了SQL的查询能力与过程式编程语言的功能,使得数据库...

    Oracle PL/SQL培训课件

    通过这个Oracle PL/SQL的培训,开发者将能够熟练地使用Oracle SQL进行数据操作,并掌握如何在Oracle数据库环境中编写存储过程、函数等更复杂的PL/SQL程序。这些知识对于在实际项目中进行高效、准确的数据管理和处理...

    oracle10g_pl/sql

    Oracle 10g PL/SQL 是Oracle数据库系统中用于创建和管理存储过程、函数、触发器等数据库对象的编程语言。本教程旨在为初学者提供一个全面的学习平台,同时也为经验丰富的开发者提供参考资料。PL/SQL是Oracle特有的...

    Oracle PL/SQL programming(5th Edition)

    ### Oracle PL/SQL Programming知识点概览 #### 一、书籍基本信息 - **书名**:Oracle PL/SQL Programming(第五版) - **作者**:Steven Feuerstein 和 Bill Pribyl - **出版日期**:2009年10月1日 - **出版社**:...

    Oracle PL/SQL best practice

    Oracle PL/SQL最佳实践 Oracle PL/SQL是一种强大的编程语言,用于在Oracle数据库环境中构建复杂的业务逻辑和数据处理任务。Steven Feuerstein,被誉为Oracle PL/SQL语言的大师,分享了他在这一领域的关键最佳实践和...

    oracle 9i pl/sql程序设计笔记

    ### Oracle 9i PL/SQL程序设计笔记精要 #### PL/SQL基础知识概览 **标题与描述**:本文档围绕“Oracle 9i PL/SQL程序设计笔记”这一核心主题,深入探讨了PL/SQL语言的基础知识及其在Oracle 9i数据库环境中的应用。...

    《精通Oracle PL/SQL》源码

    Oracle PL/SQL是一种强大的编程语言,它结合了SQL(结构化查询语言)的数据库操作能力和PL(过程化语言)的程序设计特性,是Oracle数据库系统中的核心组件之一。《精通Oracle PL/SQL》这本书深入探讨了这个语言的...

    Oracle PL/SQL by Example(4th Edition)

    《Oracle PL/SQL by Example(4th Edition)》是一本专为Oracle数据库用户设计的PL/SQL编程指南,尤其适合那些希望通过实践学习这一强大的过程式语言的开发者。本书的第四版详细介绍了Oracle PL/SQL的各种核心概念和...

Global site tag (gtag.js) - Google Analytics