Oracle学习(十一):PL/SQL

1.知识点:可以对照下面的录屏进行阅读

PL/SQL程序结构
declare
      说明部分    (变量说明,光标申明,例外说明 〕
begin
      语句序列   (DML语句〕…
exception
      例外处理语句
End;
/
------------------------------------------------------------------
--第一个PL/SQL程序:HelloWorld
set serveroutput on	--如果要在屏幕上输出信息,需要将serveroutput开关打开
declare
  --变量的说明
begin
   --程序体
   --程序包package
   dbms_output.put_line('Hello World');
end;
/
------------------------------------------------------------------

--引用型变量: 查询并打印7839的姓名和薪水

set serveroutput on

declare
  --定义变量,
  pename emp.ename%type;		--将pename的类型设置为emp表中ename的类型
  psal   emp.sal%type;	--将psal的类型设置为emp表中sal的类型

begin

  --查询:
  --ename,sal into pename,psal:将查询的ename,sal分别赋值给pename,psal按顺序赋值
  select ename,sal into pename,psal from emp where empno=7839;

  --打印
  dbms_output.put_line(pename||'的薪水是'||psal);

end;
/
------------------------------------------------------------------

--记录型变量 查询并打印7839的姓名和薪水

set serveroutput on

declare
  --定义变量,代表一行
  emp_rec emp%rowtype;
begin
  --得到一行,赋值给emp_rec
  select * into emp_rec from emp where empno=7839;

  dbms_output.put_line(emp_rec.ename||'的薪水是'||emp_rec.sal);

end;
/
------------------------------------------------------------------
--if语句:判断用户输入的数字

set serveroutput on

/*
1.提示信息
2. 接收键盘输入
num 是一个地址值

SQL优化: num绑定变量(尽量使用绑定变量)
select * from emp where deptno=10;  --> 执行计划
select * from emp where deptno=20;  --> 执行计划
-->
select * from emp where deptno=#

*/
accept num prompt '请输入一个数字';

declare
  --变量保存输入的数字
  pnum number  := #
begin
  --判断
  if pnum = 0 then
    dbms_output.put_line('您输入的是0');
  elsif pnum = 1 then
    dbms_output.put_line('您输入的是1');
  elsif pnum = 2 then
    dbms_output.put_line('您输入的是2');
  else
    dbms_output.put_line('其他数字');
  end if;
end;
/
------------------------------------------------------------------
--循环: 打印1~10,有3中方法,见下图

set serveroutput on

declare
  pnum number := 1;	--给pnum赋值1,pnum类型为number
begin
  loop
    --退出:成立退出,不成立循环
    exit when pnum > 10;

    --隐式转换,number转varchar2
    dbms_output.put_line(pnum);

    pnum := pnum + 1;

  end loop;
end;
/
------------------------------------------------------------------

光标(Cursor)==ResultSet

说明光标语法:
CURSOR  光标名  [ (参数名  数据类型[,参数名 数据类型]...)]
      IS  SELECT   语句;
用于存储一个查询返回的多行数据
例如:
cursor c1 is select ename from emp;
打开光标:      open c1;    (打开光标执行查询)
取一行光标的值:fetch c1 into pjob; (取一行到变量中)
关闭光标:      close  c1;(关闭游标释放资源)
注意: 上面的pjob必须与emp表中的job列类型一致:
定义:pjob emp.empjob%type;
------------------------------------------------------------------
--光标: 使用游标查询员工姓名和工资,并打印

/*
光标的3个属性:
%isopen 是否被打开:打开true,关闭false;
%rowcount 行数
%notfound 是否有值:没有值true,有值false;
*/

set serveroutput on

declare
  --光标
  cursor cemp is select ename,sal from emp;
  pename emp.ename%type;		--将用来接收的变量类型设置为和查询的类型相同
  psal   emp.sal%type;
begin
  open cemp;		--打开光标执行查询
  loop
    --从集合中取值
    fetch cemp into pename,psal;
    --光标中没有值时退出
    exit when cemp%notfound;

    dbms_output.put_line(pename||'的薪水是'||psal);

  end loop;
  close cemp;
end;
/
------------------------------------------------------------------
--光标练习:给员工涨工资  总裁1000 经理800 其他400
--光标同时能打开的最大数量默认为300个
/*
SQL> show parameters cursor

NAME                                 TYPE        VALUE
------------------------------------ ----------- --------
cursor_sharing                       string      EXACT
cursor_space_for_time                boolean     FALSE
open_cursors                         integer     300
session_cached_cursors               integer     20

*/
set serveroutput on
declare
  --光标代表员工
  cursor cemp is select empno,job from emp;
  pempno emp.empno%type;
  pjob   emp.job%type;
begin
  open cemp;
  loop
    fetch cemp into pempno,pjob;
    exit when cemp%notfound;

    --判断
    if pjob = 'PRESIDENT' then update emp set sal=sal+1000 where empno=pempno;	--总裁涨1000
      elsif pjob = 'MANAGER' then update emp set sal=sal+800 where empno=pempno; --经理涨800
      else update emp set sal=sal+400 where empno=pempno;	--其他涨400
    end if;
  end loop;
  close cemp;

  --提交: 隔离级别
  commit;

  dbms_output.put_line('完成');
end;
/
------------------------------------------------------------------
--带参数的光标:查询某个部门的员工姓名 

set serveroutput on

declare
  --定义一个带参数的光标
  cursor cemp(pdno number) is  select ename from emp where deptno=pdno;
  pename emp.ename%type;
begin
  open cemp(20);	--打开光标,并传递参数
  loop
    fetch cemp into pename;
    exit when cemp%notfound;

    dbms_output.put_line(pename);

  end loop;
  close cemp;
end;
/
------------------------------------------------------------------
Oracle的异常处理
1.系统定义例外
No_data_found    (没有找到数据)
Too_many_rows          (select …into语句匹配多个行)
Zero_Divide   ( 被零除)
Value_error     (算术或转换错误)
Timeout_on_resource      (在等待资源时发生超时)

--举例 Zero_Divide   ( 被零除)

set serveroutput on
declare
  pnum number;
begin

  pnum := 1/0;

exception
  when Zero_Divide then dbms_output.put_line('1: 0不能做被除数');
                        dbms_output.put_line('2: 0不能做被除数');
  when Value_error then dbms_output.put_line('算术错');
  when others then dbms_output.put_line('其他例外');
end;
/

用户自己定义的例外
--自定义例外: 查询50号部门的员工姓名

set serveroutput on

declare
  cursor cemp is select ename from emp where deptno=50;
  pename emp.ename%type;

  --自定义例外
  no_emp_found exception;
begin
  open cemp;
  --取一个员工
  fetch cemp into pename;
  if cemp%notfound then
    raise no_emp_found;
  end if;

/*
  if cemp%isopen then
    close no_emp_found;
  end if;
*/
  close cemp;

exception
  when no_emp_found then dbms_output.put_line('没有找到员工');
  when others then dbms_output.put_line('其他例外');

end;
/

图:循环的3种写法,文中采用右上角的方法。

2.在Sqlplus下实际执行的结果录屏

SQL> --第一个PL/SQL程序:HelloWorld
SQL> set serveroutput on	--如果要在屏幕上输出信息,需要将serveroutput开关打开
SQL> declare
  2    --变量的说明
  3  begin
  4     --程序体
  5     --程序包package
  6     dbms_output.put_line('Hello World');
  7  end;
  8  /

Hello World

PL/SQL procedure successfully completed

SQL>
SQL> --引用型变量: 查询并打印7839的姓名和薪水
SQL> set serveroutput on
SQL> declare
  2    --定义变量,
  3    pename emp.ename%type;		--将pename的类型设置为emp表中ename的类型
  4    psal   emp.sal%type;	--将psal的类型设置为emp表中sal的类型
  5
  6  begin
  7
  8    --查询:
  9    --ename,sal into pename,psal:将查询的ename,sal分别赋值给pename,psal按顺序赋值
 10    select ename,sal into pename,psal from emp where empno=7839;
 11
 12    --打印
 13    dbms_output.put_line(pename||'的薪水是'||psal);
 14
 15  end;
 16  /

KING的薪水是5000

PL/SQL procedure successfully completed

SQL>
SQL> -记录型变量 查询并打印7839的姓名和薪水
SQL> set serveroutput on
SQL> declare
  2    --定义变量,代表一行
  3    emp_rec emp%rowtype;
  4  begin
  5    --得到一行,赋值给emp_rec
  6    select * into emp_rec from emp where empno=7839;
  7
  8    dbms_output.put_line(emp_rec.ename||'的薪水是'||emp_rec.sal);
  9
 10  end;
 11  /

KING的薪水是5000

PL/SQL procedure successfully completed

SQL>
SQL> --if语句:判断用户输入的数字
SQL> set serveroutput on
SQL> /*
  2  1.提示信息
  3  2. 接收键盘输入
  4  num 是一个地址值
  5
  6  SQL优化: num绑定变量(尽量使用绑定变量)
  7  select * from emp where deptno=10;  --> 执行计划
  8  select * from emp where deptno=20;  --> 执行计划
  9  -->
 10  select * from emp where deptno=#
 11
 12  */
 13  accept num prompt '请输入一个数字';
SQL> declare
  2    --变量保存输入的数字
  3    pnum number  := #
  4  begin
  5    --判断
  6    if pnum = 0 then
  7      dbms_output.put_line('您输入的是0');
  8    elsif pnum = 1 then
  9      dbms_output.put_line('您输入的是1');
 10    elsif pnum = 2 then
 11      dbms_output.put_line('您输入的是2');
 12    else
 13      dbms_output.put_line('其他数字');
 14    end if;
 15  end;
 16  /

您输入的是2

PL/SQL procedure successfully completed

SQL>
SQL> --循环: 打印1~10
SQL> set serveroutput on
SQL> declare
  2    pnum number := 1;	--给pnum赋值1,pnum类型为number
  3  begin
  4    loop
  5      --退出:成立退出,不成立循环
  6      exit when pnum > 10;
  7
  8      --隐式转换,number转varchar2
  9      dbms_output.put_line(pnum);
 10
 11      pnum := pnum + 1;
 12
 13    end loop;
 14  end;
 15  /

1
2
3
4
5
6
7
8
9
10

PL/SQL procedure successfully completed

SQL>
SQL> -光标: 使用游标查询员工姓名和工资,并打印
SQL> /*
  2  光标的3个属性:
  3  %isopen 是否被打开:打开true,关闭false;
  4  %rowcount 行数
  5  %notfound 是否有值:没有值true,有值false;
  6  */
SQL> set serveroutput on
SQL> declare
  2    --光标
  3    cursor cemp is select ename,sal from emp;
  4    pename emp.ename%type;		--将用来接收的变量类型设置为和查询的类型相同
  5    psal   emp.sal%type;
  6  begin
  7    open cemp;		--打开光标执行查询
  8    loop
  9      --从集合中取值
 10      fetch cemp into pename,psal;
 11      --光标中没有值时退出
 12      exit when cemp%notfound;
 13
 14      dbms_output.put_line(pename||'的薪水是'||psal);
 15
 16    end loop;
 17    close cemp;
 18  end;
 19  /

SMITH的薪水是800
ALLEN的薪水是1600
WARD的薪水是1250
JONES的薪水是2975
MARTIN的薪水是1250
BLAKE的薪水是2850
CLARK的薪水是2450
SCOTT的薪水是3000
KING的薪水是5000
TURNER的薪水是1500
ADAMS的薪水是1100
JAMES的薪水是950
FORD的薪水是3000
MILLER的薪水是1300

PL/SQL procedure successfully completed

SQL> --光标练习:给员工涨工资  总裁1000 经理800 其他400
SQL> --先查询没涨之前的
SQL> select * from emp;

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
 7369 SMITH      CLERK      7902 1980/12/17     800.00               20
 7499 ALLEN      SALESMAN   7698 1981/2/20     1600.00    300.00     30
 7521 WARD       SALESMAN   7698 1981/2/22     1250.00    500.00     30
 7566 JONES      MANAGER    7839 1981/4/2      2975.00               20
 7654 MARTIN     SALESMAN   7698 1981/9/28     1250.00   1400.00     30
 7698 BLAKE      MANAGER    7839 1981/5/1      2850.00               30
 7782 CLARK      MANAGER    7839 1981/6/9      2450.00               10
 7788 SCOTT      ANALYST    7566 1987/4/19     3000.00               20
 7839 KING       PRESIDENT       1981/11/17    5000.00               10
 7844 TURNER     SALESMAN   7698 1981/9/8      1500.00      0.00     30
 7876 ADAMS      CLERK      7788 1987/5/23     1100.00               20
 7900 JAMES      CLERK      7698 1981/12/3      950.00               30
 7902 FORD       ANALYST    7566 1981/12/3     3000.00               20
 7934 MILLER     CLERK      7782 1982/1/23     1300.00               10

14 rows selected

SQL> --执行PLSQL语句
SQL>
SQL> set serveroutput on
SQL> declare
  2    --光标代表员工
  3    cursor cemp is select empno,job from emp;
  4    pempno emp.empno%type;
  5    pjob   emp.job%type;
  6  begin
  7    open cemp;
  8    loop
  9      fetch cemp into pempno,pjob;
 10      exit when cemp%notfound;
 11
 12      --判断
 13      if pjob = 'PRESIDENT' then update emp set sal=sal+1000 where empno=pempno;	--总裁涨1000
 14        elsif pjob = 'MANAGER' then update emp set sal=sal+800 where empno=pempno; --经理涨800
 15        else update emp set sal=sal+400 where empno=pempno;	--其他涨400
 16      end if;
 17    end loop;
 18    close cemp;
 19
 20    --提交: 隔离级别
 21    commit;
 22
 23    dbms_output.put_line('完成');
 24  end;
 25  /

完成

PL/SQL procedure successfully completed

SQL> --查询执行PLSQL语句后的薪水
SQL> select * from emp;

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
 7369 SMITH      CLERK      7902 1980/12/17    1200.00               20
 7499 ALLEN      SALESMAN   7698 1981/2/20     2000.00    300.00     30
 7521 WARD       SALESMAN   7698 1981/2/22     1650.00    500.00     30
 7566 JONES      MANAGER    7839 1981/4/2      3775.00               20
 7654 MARTIN     SALESMAN   7698 1981/9/28     1650.00   1400.00     30
 7698 BLAKE      MANAGER    7839 1981/5/1      3650.00               30
 7782 CLARK      MANAGER    7839 1981/6/9      3250.00               10
 7788 SCOTT      ANALYST    7566 1987/4/19     3400.00               20
 7839 KING       PRESIDENT       1981/11/17    6000.00               10
 7844 TURNER     SALESMAN   7698 1981/9/8      1900.00      0.00     30
 7876 ADAMS      CLERK      7788 1987/5/23     1500.00               20
 7900 JAMES      CLERK      7698 1981/12/3     1350.00               30
 7902 FORD       ANALYST    7566 1981/12/3     3400.00               20
 7934 MILLER     CLERK      7782 1982/1/23     1700.00               10

14 rows selected

SQL> --对比涨之前,可以看出涨工资成功
SQL>
SQL> --带参数的光标:查询某个部门的员工姓名
SQL> set serveroutput on
SQL> declare
  2    --定义一个带参数的光标
  3    cursor cemp(pdno number) is  select ename from emp where deptno=pdno;
  4    pename emp.ename%type;
  5  begin
  6    open cemp(20);	--打开光标,并传递参数
  7    loop
  8      fetch cemp into pename;
  9      exit when cemp%notfound;
 10
 11      dbms_output.put_line(pename);
 12
 13
 14    end loop;
 15    close cemp;
 16  end;
 17  /

SMITH
JONES
SCOTT
ADAMS
FORD

PL/SQL procedure successfully completed

SQL>
SQL> --举例 Zero_Divide   ( 被零除)
SQL> set serveroutput on
SQL> declare
  2    pnum number;
  3  begin
  4
  5    pnum := 1/0;
  6
  7  exception
  8    when Zero_Divide then dbms_output.put_line('1: 0不能做被除数');
  9                          dbms_output.put_line('2: 0不能做被除数');
 10    when Value_error then dbms_output.put_line('算术错');
 11    when others then dbms_output.put_line('其他例外');
 12  end;
 13  /

1: 0不能做被除数
2: 0不能做被除数

PL/SQL procedure successfully completed

SQL>
SQL> --自定义例外: 查询50号部门的员工姓名
SQL> set serveroutput on
SQL> declare
  2    cursor cemp is select ename from emp where deptno=50;
  3    pename emp.ename%type;
  4
  5    --自定义例外
  6    no_emp_found exception;
  7  begin
  8    open cemp;
  9    --取一个员工
 10    fetch cemp into pename;
 11    if cemp%notfound then
 12      raise no_emp_found;
 13    end if;
 14
 15    close cemp;
 16
 17  exception
 18    when no_emp_found then dbms_output.put_line('没有找到员工');
 19    when others then dbms_output.put_line('其他例外');
 20
 21  end;
 22  /

没有找到员工

PL/SQL procedure successfully completed

SQL> spool off
Stopped spooling to c:\PLSQL.txt

Oracle学习(十一):PL/SQL,布布扣,bubuko.com

时间: 2024-08-02 02:49:40

Oracle学习(十一):PL/SQL的相关文章

ORACLE学习之PL/SQL编程——本地动态SQL

目录 读前注意与概述 动态SQL简介 使用EXCUTE IMMEDIATE语句 处理DDL和DCL语句 处理DML语句 处理单行查询 处理多行查询 在动态SQL中使用批量绑定 读前注意与概述 当编写PL/SQL块时,静态SQL语句只能完成一些固定任务.为了使得PL/SQL块可以灵活的处理SQL语句,需要使用动态SQL.动态SQL包括本地动态SQL和DBMS_SQL动态SQL两种实现方法,其中本地动态SQL只适用于oracle服务器端,而DBMS_SQL动态SQL不仅适用于oracle服务器端,而

Oracle学习之PL/SQL块

1.简单开始 DECLAREname varchar2(20);BEGIN select first_name into name from hr.employees where employee_id=&no; dbms_output.put_line(name);EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('该雇员不存在!');END;/ 2. 简单--- DECLARETYPE emp_record_type IS RECO

免安装Oracle客户端和PL/SQL

写在前面: Oracle是典型的C/S结构,服务端提供oracle服务的实例,主要用于数据库的管理,对象的管理与存储.数据的 存储.查询.数据库资源的监控.监听等一些服务.而客户端只是一个与服务端交互的工具,如sqlplus,在sqlplus 里执行SQL语句传到服务端,服务端进行解析后执行SQL里的操作,并将操作结果输出到客户端.这就完成了一个客户 端与服务端交互的过程.简单点说,客户端就像一个远程桌面工具,只负责提供链接后台服务器的界面,具体的处理 操作都在服务器上. 上一篇文章我们主要讲解

每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQL程序设计终极指南>志在打造PL/SQL领域最为系统.全面.实战.权威的著作,通过一系列非常突出的优势在大量的同类书中脱颖而出,成为该领域的标准读物. PL/SQL本身涉及的知识点浩瀚.庞杂,初学者根本无法依靠自身能力理清头绪,学习成本极高.本书对知识点进行了体系化的梳理,化繁杂为有序,突出重点,直指核

Oracle 11g 的PL/SQL函数结果缓存

模仿Oracle性能诊断艺术中的例子做了两个试验,书上说如果不用RELIES_ON,则函数依赖的对象发生的变更操作就不会导致结果缓存的失效操作(result_cache RELIES_ON(test1,test2)),试验证明不对,函数f1()并没有使用RELIES_ON,但表上的变化影响到了函数. C:\Documents and Settings\guogang>sqlplus gg_test/[email protected]_gg SQL*Plus: Release 10.2.0.1.0

Oracle 客户端安装 + pl/sql工具安装配置

Oracle 客户端安装 +  pl/sql工具安装配置 下载oracle客户端,并在本地安装. 11g下载地址为: http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 10g下载地址为: http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 根据自己机器或者oracle服

《oracle每日一练》免安装Oracle客户端使用PL/SQL

免安装Oracle客户端使用PL/SQL Oracle客户端挺招人烦的,部署连接它的应用通常需要先安装它的客户端,安装程序要求在目标机器上写注册表,假设你没有洁癖的话,你仍可能被下面的事情绊住:当你的机器上的其他程序依赖于x64的Oracle的程序,并且它们很有可能根本不是你写的,因此你还不敢随便乱动服务器,但是你可能需要一个PL/SQL用来在相同的环境下执行查询,这个时候你还是需要一个免安装的办法来处理这个问题. 1.下载Oracle Instant Client (32-bit) 因为我的P

免安装Oracle客户端使用PL/SQL连接Oracle的2种方法

作者:netshuai  来源:博客园  发布时间:2009-10-23 09:19  阅读:171 次  原文链接   [收藏] 方法一: 大家都知道,用PL/SQL连接Oracle,是需要安装Oracle客户端软件的.有没要想过不安装Oracle客户端直接连接Oracle呢? 其实我一直想这样做,因为这个客户端实在太让人讨厌了!!!不但会安装一个JDK,而且还会把自己放在环境变量的最前面,会造成不小的麻烦. 其实我之前问过很多人的,但是他们都说一定需要安装Oracle客户端的.......直

Oracle学习笔记三 SQL命令

SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)               下面是这四种SQL语言的详细笔记: Oracle学习笔记三 SQL命令(二):SQL操作语言类别 Oracle数据类型 创建表时,必须为各个列指定数据类型 以下是 Oracle 数据类型的类别: 字符数据类型 CHAR类型 当需要固定长度的字符串时,使用 CHAR 数据类型. CHAR 数据类型存储字母数字值. CH