PL/SQL程序结构及组成

什么是PL/SQL?

•PL/SQL(Procedure Language/SQL)
•PLSQL是Oracle对sql语言的过程化扩展
•指在SQL命令语言中添加了过程处理语句(如分支、循环等)。使SQL语言具有过程处理能力。


SQL长处

交互式非过程化;
数据操纵功能强;
自己主动导航语句简单;
调试easy使用方便。

把SQL语言的数据操纵能力与过程语言的数据处理能力结合起来,使得PLSQL面向过程但比过程语言简单、高效、灵活和有用。

经常使用的结合语言

lPlsql(oracle),Transact-sql(SQLserver)



PL/SQL的程序结构

declare

说明部分    (变量说明,光标申明,例外说明〕

begin

语句序列   (DML语句〕…

exception

例外处理语句

End;

/


变量和常量的说明







l说明变量 (char,varchar2,
date, number, boolean,long)
基本数据类型变量 

 1. 基本数据类型 

     Number 数字型  

     Int 整数型  

     Pls_integer 整数型。产生溢出时出现错误  

     Binary_integer 整数型。表示带符号的整数  

     Char 定长字符型,最大255个字符  

     Varchar2 变长字符型。最大2000个字符  

     Long 变长字符型,最长2GB  

     Date 日期型  

     Boolean 布尔型(TRUE、FALSE、NULL三者取一)  

     在PL/SQL中使用的数据类型和Oracle数据库中使用的数据类型。有的含义是全然一致的,

有的是有不同的含义的。

2. 基本数据类型变量的定义方法 

     变量名  类型标识符  [not null]:=值; 

     declare 

         age number(3):=26; --长度为3,初始值为26 

     begin 

         commit; 

     end; 

     当中。定义常量的语法格式: 

     常量名  constant 类型标识符  [not null]:=值; 

     declare 

         pi constant number(9):=3.1415926;--为pi的数字型常量,长度为9,初始值为3.1415926 

     begin 

         commit; 

     end; 


if语句

三种if语句

1.      IF  条件 THEN 语句1;

语句2;

END IF;


2. IF 条件 THEN  语句序列1;

ESLE   语句序列 2;

END   IF;


3. IF   条件  THEN 语句;

ELSIF  语句 THEN  语句;

ELSE    语句;

END  IF;

小知识:获取从键盘输入的数据

•从键盘输入:

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

•得到键盘输入的值:

pnum number := #



循环语句

三种循环语句

1. WHILE  total <= 25000 LOOP

.. .

total : = total + salary;

END LOOP;

2.  Loop

EXIT [when   条件];

……

End loop


3.   FOR   I  IN   1 . . 3    LOOP

语句序列 ;

END    LOOP ;

光标(Cursor)==ResultSet

说明光标语法:

1.定义光标

CURSOR  光标名 [ (參数名 数据类型[,參数名 数据类型]...)]

IS SELECT   语句;

用于存储一个查询返回的多行数据

比如:

cursorc1 is select
ename from
emp;

2.打开光标:                 openc1;    (打开光标运行查询)

3.取一行光标的值:fetch c1 into pjob;(取一行到变量中)

4.关闭光标:          close  c1;(关闭游标释放资源)

注意: 上面的pjob必须与emp表中的job列类型一致:
•定义:pjobemp.empjob%type;

演示样例

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcWh3YzIwMDk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

带參数的光标

定义语句:

cursor c2(jobc
varchar2)

is

select ename,salfrom emp

where job=jobc;

运行语句:

Open c2(‘clerk’);

Oracle的异常处理

例外

l例外是程序设计语言提供的一种功能,用来增强程序的健壮性和容错性。

系统定义例外

•No_data_found   (没有找到数据)
•Too_many_rows          (select …into语句匹配多个行)
•Zero_Divide  ( 被零除)
•Value_error    (算术或转换错误)
•Timeout_on_resource      (在等待资源时发生超时)

用户定义例外及处理例外

DECLARE

My_job   char(10);

v_sal  emp.sal%type;

No_data    exception;

cursor c1 is select distinct jobfrom emp    order by job;



begin

open c1;

Fetch c1 into v_job;

IF c1%notFOUND then raiseno_data;

end if;

EXCEPTION

WHEN no_data  THEN insert into empvalues(‘fetch语句没有获得数据或数据已经处理完');

END;




在declare节中定义例外  
•out_of  exception ;
在可行语句中引起例外 
•raise out_of ;
在Exception节处理例外
•when Out_of then …



两种赋值语句

利用:=赋值

lvar1:='this is a argument';

lemp_rec.sal:=
sal*2 +
nvl(comm,0);

lsum_sal:=sum_sal+v_sal;


利用into赋值

lFETCH c1 INTO e_eno , e_sal ;




commit语句

l结束当前事务,
使当前事务所运行的所有改动永久化。

在运行完DML语句之后一定不要忘记在代码后面加上commit来提交!



凝视

两种凝视格式:

-- This is a comment

/* This is a comment */




实例演示样例

演示样例1

为员工长工资。从最低工资调起每人长10%,但工资总额不能超过5万元,请计算长工资的人数和长工资后的工资总额,并输出输出长工资人数及工资总额。

可能用到的SQL语句:
•select empno,sal from emp  order by sal ;
•select sum(sal) into s_sal from emp;



答案:

/*

为员工长工资。

从最低工资调起每人长10%,但工资总额不能超过50万元,

请计算长工资的人数和长工资后的工资总额,并输出输出长工资人数及工资总额。





先写出可能用到的sql语句

select empno,sal from emp order by sal;

select sum(sal) from emp;

*/





set serveroutput on





declare

   cursor c1 is select empno,sal from emp order by sal;

   salTotal NUMBER; --记录工资总额

   empCount NUMBER := 0; --涨工资的人数

   

   pempno emp.empno% TYPE; --记录员工的编号

   psal   emp.sal%type;    --记录员工的工资

begin

  --得到当前总工资

  select sum(sal) into salTotal from emp;

  --打开游标

  open c1;

  --运行循环

  while salTotal <= 50000

  loop

      fetch c1 into pempno, psal;--取出一条记录

      exit when c1%notfound;

      update emp set sal = sal * 1.1 where empno = pempno; --运行加薪

      --记录涨工资后的总额

      salTotal := salTotal + psal*0.1;

      --记录涨工资的人数

      empCount := empCount + 1;

  end loop;

  close c1;

  commit;

  

  dbms_output.put_line('涨工资人数:' || empCount || '  工资总额:' || salTotal);

end;

/


watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcWh3YzIwMDk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">



演示样例2

l用PL/SQL语言编写一程序。实现按部门分段(6000以上、(6000。3000)、3000元下面)统计各工资段的职工人数、以及各部门的工资总额(工资总额中不包含奖金)。參考例如以下格式:

数 
3000-6000  大于6000 工资总额

10              2                  1                       0           8750

20             3                  2                       0         10875

30             6                  0                       0           9400

l提示:能够创建一张新表用于保存数据

createtable msg1

(deptno  number,

emp_num1 number,

emp_num2 number,

emp_num3 number,

sum_salnumber);






/*

用PL/SQL语言编写一程序。实现按部门分段(6000以上、(6000,3000)、3000元下面)统计各工资段的职工人数、

以及各部门的工资总额(工资总额中不包含奖金)





先写出可能用到的查询语句

a = select distinct deptno from dept;

select sal from emp where deptno= a中的某个值;





关于结果的输出:

1. 直接输出在屏幕上

2. 输出到一张表中

create table salcount

(deptno number, --部门号

 sg1    int,    --3000下面的人数

 sg2    int,    -- 3000~6000的人数

 sg3    int     -- 6000以上的人数

);

*/





declare

   --定义两个游标保存结果

   cursor c1 is select distinct deptno from dept;

   cursor c2(pdno number) is select sal from emp where deptno=pdno;

   

   --定义三个变量用于保存每一个部门三个工资段的人数

   count1 NUMBER;

   count2 number;

   count3 number;

   

   --记录c1游标中的部门号

   pdeptno dept.deptno% TYPE;

   --记录c2游标中的薪水值

   psal emp.sal% TYPE;

begin

  open c1;--打开c1 获得全部部门号

    loop

      fetch c1 into pdeptno;--取一个部门号

      exit when c1%notfound;

      --计数器清零      

      count1 := 0; 

      count2 := 0;

      count3 := 0;

      --得到该部门的全部员工

      open c2(pdeptno);

        loop

          fetch c2 into psal; --得到该员工的工资

          exit when c2%notfound;

          if psal <=3000 then count1 := count1 + 1;

          elsif psal > 3000 and psal <=6000 then count2 := count2 + 1;

          else  count3 := count3 + 1;

          end if;

        end loop;

      close c2;

      

      --保存该部门的统计结果

      insert into salcount values(pdeptno,count1,count2,count3);

      commit;

    end loop;

  close c1;

end;

/

   

   

   

   

   

   

   

   

   

   

   

   

Oracle学习(11):PLSQL程序设计的更多相关文章

  1. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  2. Oracle学习线路

    出自huyangg的博客,地址是:oracle学习路线图 1.sql.pl/sql(网上有很多的视频,可以做一个简单的入手,然后看几本书,多做实验)    作为oracle的基本功,需要大家对sql和 ...

  3. Oracle学习系列1-7

    Oracle学习系列1 两个服务必须启动: OracleOraDb10g*TNListener 和 OracleService*** 使用sqlplusw先进行环境的设置 set linesize 3 ...

  4. 解决中64位Win7系统上PLSQL无法连接ORACLE的方法(PLSQL无法识别ORACLE_HOME的配置)

    最近新安装了64位的Win7系统,工作中需要用oracle数据库,而数据库是公司IT的DBA进行管理和维护的. 我们只需要连接上去进行使用就可以了,于是我就在自己的机器上安装了oracle clien ...

  5. oracle学习 第二章 限制性查询和数据的排序 ——03

    这里.我们接着上一小节2.6留下的问题:假设要查询的字符串中含有"_"或"%".又该如何处理呢? 開始今天的学习. 2.7  怎样使用转义(escape)操作符 ...

  6. oracle学习 第一章 简单的查询语句 ——03

    1.1最简单的查询语句 例 1-1 SQL> select * from emp; 例 1-1 结果 这里的 * 号表示全部的列.它与在select 之后列出全部的列名是一样的.查询语句以分号( ...

  7. Oracle:使用PL-SQL登录时报ORA-12541:无监听程序的解决办法

    背景: 在自己公司安装的Oracle,当时Oracle的监听地址都是写的公司的地址 后来由于项目需要,办公地点转移到了客户处, 大概有半年没有以sys用户登录数据库了. 最近在上下班途中学习Djang ...

  8. csharp: ODP.NET,System.Data.OracleClient(.net 4.0) and System.Data.OleDb读取Oracle g 11.2.0的区别

    ODP.NET: 引用: using Oracle.DataAccess; //Oracle g 11.2.0 using Oracle.DataAccess.Client; using Oracle ...

  9. 【oracle】oracle学习笔记2--scoot账户的激活与解锁

    1.用sysz账户as sysddba登录,并执行scott.sql文件.我的文件目录是C:\oraclexe\app\oracle\product\11.2.0\server\rdbms\admin ...

  10. Oracle学习指南

    Oracle学习指南 你走的那天,我决定不落泪,迎着风撑着眼帘用力不眨眼 创建数据库.创建用户.创建表空间.创建表.插入数据..... 1.用系统用户登录,任选系统用户 代码: >>sql ...

随机推荐

  1. LightOJ--1149--Factors and Multiples(二分图好题)

    Factors and Multiples Time Limit: 2000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu ...

  2. Juniper路由器

    Juniper路由器入门之一:需要子接口的端口配置 set interfaces fe-2/0/1 vlan-tagging              ――――在配置接口启用封装VLAN set in ...

  3. V8 引擎是如何工作的?

    V8 引擎是如何工作的? 本文翻译自:How the V8 engine works? ​ V8是谷歌德国开发中心构建的一个JavaScript引擎.它是由C++编写的开源项目,同时被客户端(谷歌浏览 ...

  4. ES6 Proxy 性能之我见

    ES6 Proxy 性能之我见 本文翻译自https://thecodebarbarian.com/thoughts-on-es6-proxies-performance Proxy是ES6的一个强力 ...

  5. 8) 十分钟学会android--Activity的生命周期之停止与重启

    恰当的停止与重启我们的activity是很重要的,在activity生命周期中,他们能确保用户感知到程序的存在并不会丢失他们的进度.在下面一些关键的场景中会涉及到停止与重启: 用户打开最近使用app的 ...

  6. 相似图像识别检 —基于图像签名(LSH)

    原文链接:http://grunt1223.iteye.com/blog/828192 参考:人工智能,一种现代方法 第 617页,且原始论文给出了完整的证明过程.在ANN方法中,LSH算一种可靠的紧 ...

  7. jQuery访问json文件

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. concurrently - npm 同时运行前端和后台服务

    项目基于vue(前端)+node(后台),需要启动两个服务 0.文件夹结构及package.json内容: 1.客户端 npm run dev 2.服务器 cd server npm run serv ...

  9. 网站出现502 bad getway

    最近项目之余,领导叫解决下系统网站经常出现502的问题,作为小头头的我,怎能不顶上. 流程开始走起,先查nginx,嗯,配置是大众的.是不是缓存溢出了呢.调节buffer的值 .貌似也没什么影响啊.5 ...

  10. Nginx1.14.2新增tcp/udp代理stream

    [root@rhel nginx-1.12.1]# ./configure --help --help print this message --prefix=PATH set installatio ...