什么是PL/SQL
PL/SQL也是一种程序语言,被称作支持SQL的程序语言(Program Language),是Oracle数据库对SQL语句的扩展,在普通的SQL语言中增加了编程语言的特点 ;
数据操作和查询语句被包含在PL/SQL代码的过程性单元中,经过逻辑判断、循环等操作完成复杂的功能或者计算.
使用PL/SQL可以编写具有很多高级功能的程序,虽然这些功能可以通过多个SQL语句来完成同样的功能,但是PL/SQL具有如下的优点:
1、使一组语句功能形成模块化程序开发
2、使用过程性语言控制程序结构
3、可以对程序中的错误进行处理
4、具有较好的可移植性
5、集成在数据库中,调用更快
6、减少了网络的交互,有助于提高程序性能
PL/SQL提供了一些新的特性,可以进行复杂的信息处理
1、软件包
2、触发器
3、存储过程
4、函数
5、异常处理
6、PL/SQL可以使用所有的SQL数据操作,游标控制和事务控制命令,以及所有的SQL函数和运算符.PL/SQL完全支持SQL数据类型
SQL,SQLPLUS,PL/SQL之间的关系:
可以把oracle数据库看作餐馆的厨房,而SQLPLUS是将菜单(脚本,命令或程序)送进厨房(即数据库)的服务员.在厨房中有两个厨师,SQL 和PL/SQL.作为服务员的SQLPLUS知道它可以处理那些命令,那些命令要交给厨师处理.在SQLPLUS提示符下输入的执行命令或程序就象顾客点的菜.对于每个顾客点的菜,厨师都知道如何进行处理,就像在厨师心中的菜谱一样,PL/SQL也存储常用命令的食谱(这些元素称为触发器,存储函数,存储过程,软件包).有些大菜需要多个厨师共同处理,大多数的程序都是结合了SQL和PL/SQL,并在他们之间来回的传递信息,从而处理脚本或程序.顾客点的菜作好之后,再由作为服务员的SQL*PLUS将执行的结果显示给用户
PL/SQL中起作用的部分都是由基本块组成的.基本块有四个
组成部分
声明部分:DECLARE – 可选部分
变量、常量、游标、用户定义异常声明
执行体开始部分:BEGIN – 必要部分
SQL语句
PL/SQL语句
异常处理部分: EXCEPTION – 可选部分
程序出现异常时,捕捉异常并处理异常
执行体结束:END; – 必要部分
DECLARE
-- 在declare部分声明变量,常量等
-- 声明 变量的规范:变量名称 变量类型 [:=缺省值];
V_DEPTNO NUMBER;
BEGIN
-- 在BEGIN部分可以写 SQL语句,PL/SQL语句
-- 在BEGIN部分可以使用DECLARE部分声明的变量,常量
DBMS_OUTPUT.put_line('欢迎使用PL/SQL,执行查询语句之前,V_DEPTNO=' || V_DEPTNO);
-- 把查询语句查询的结果赋值给V_DEPTNO这个变量
SELECT DEPTNO INTO V_DEPTNO FROM EMP WHERE EMPNO = 7369; -- PL/SQL语句
dbms_output.put_line('执行查询语句后,V_DEPTNO=' || V_DEPTNO);
DELETE FROM EMP WHERE DEPTNO = V_DEPTNO; -- SQL语句
DELETE FROM DEPT WHERE DEPTNO = V_DEPTNO;
END;
1、在声明部分声明和初始化变量
2、在执行部分为变量赋新值,或在表达式中使用变量
3、在异常处理部分也可以使用变量
4、通过参数把值传递到PL/SQL 块中
5、通过输出变量或者参数将值传出PL/SQL块
DECLARE
v_total_sal NUMBER(9, 2) := 0; -- PL/SQL中赋值语句
c_tax_rate CONSTANT NUMBER(3, 2) := 8.25; -- 常量只能被赋值一次
v_gender CHAR(1);
v_valid BOOLEAN NOT NULL := TRUE;
V_B BOOLEAN;
V_NUM1 NUMBER(2) := 11;
V_NUM2 NUMBER(2) := 10;
BEGIN
dbms_output.put_line('v_total_sal=' || v_total_sal);
-- = 相当于Java中的 ==的功能,执行逻辑比较操作
V_B := (V_NUM1 = V_NUM2);
IF( V_B ) THEN
DBMS_OUTPUT.put_line('OK');
ELSE
DBMS_OUTPUT.put_line('NOT OK');
END IF;
END;
PL/Sql中的变量类型:简单变量、复合(组合)变量
1、简单变量不包括任何组件,只能保存一个值
基本类型包括三大类:字符,数字,日期
变量 | 含义 |
---|---|
BINARY_INTEGER | 整形数字 |
NUMBER [(precision, scale)] | 数字类型 |
CHAR [(maximum_length)] | 定长字符类型 |
VARCHAR2(maximum_length) | 变长字符类型 |
DATE | 日期类型 |
LONG | 长字符类型 |
LONG RAW | 长二进制类型 |
CLOB / BLOB / BFILE | 大对象类型(字符大对象,二 进制大对象,操作系统文件大对象) |
BOOLEAN | 布尔类型,有效值为 TRUE,FALSE,NULL |
简单变量的声明:
v_gender CHAR(1);
v_count BINARY_INTEGER := 0;
v_total_sal NUMBER(9,2) := 0;
v_order_date DATE := SYSDATE + 7;
c_tax_rate CONSTANT NUMBER(3,2) := 8.25;
v_valid BOOLEAN NOT NULL := TRUE;
2、复合类型
复合变量也叫做组合变量.在复合变量中包含多个内部的组件,每个组件都可以单独存放值.一个复合变量可以存放多个值。与简单变量类型不同,复合变量类型不是数据库中已经存在的数据类型,所以复合变量在声明类型之前,首先要创建使用到的复合类型,然后将变量声明为复合变量
复合数据类型:
PL/SQL TABLES 表类型
PL/SQL RECORDS 记录类型
复合类型被创建后,可以被使用多次定义多个变量
复合类型TABLE:
(1)表类型类似于其他编程语言中的数组类型
(2)由两个组件组成:
数据类型为BINARY_INTEGER(整形数字)的主键
数据类型为一个确定的简单类型的列
(3)Table类型没有长度限制,可以动态增长.表类型中的第二部分类似与数组中的值,这个部分必须是一个已经确定的简单类型,不能是其他的复合类型
(4)表类型的结构很像数组.第一部分使一个按1递增的整形数字,起到数字索引的作用,第二部分使一种确定的简单类型,用来存放每个索引号对应的具体的数值
DECLARE
-- 在声明部分声明表类型
TYPE NAMEED_TABLE_TYPE IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;
-- 使用声明的表类型来声明变量
V_TABLE1 NAMEED_TABLE_TYPE;
BEGIN
-- 给表类型的变量赋值,可以通过索引来访问表类型的变量
-- 表类型的变量没有长度的限制
V_TABLE1(1) := 'Hello1';
V_TABLE1(2) := 'Hello2';
V_TABLE1(3) := 'Hello3';
V_TABLE1(4) := 'Hello1';
V_TABLE1(5) := '工程师';
V_TABLE1(6) := '工程师';
DBMS_OUTPUT.put_line('V_TABLE1(1)=' || V_TABLE1(1) || ',V_TABLE1(2)=' ||
V_TABLE1(2) || ',V_TABLE1(3)=' || V_TABLE1(3) ||
',V_TABLE1(4)=' || V_TABLE1(1) || ',V_TABLE1(5)=' ||
V_TABLE1(5) || ',V_TABLE1(6)=' || V_TABLE1(6));
END;
复合类型RECODES:
(1)复合类型中的RECODES类型是由多个组件组成的一种类型.包含一个或几个组件,每个组件称为一个域(FIELD),域的数据类型可以是简单变量类型、另一个RECORD类型或PL/SQL的TABLE类型
(2)在使用RECORD变量时把多个域的集合作为一个逻辑单元使用,对记录类型变量赋值或引用,都需要使用“记录变量名.域名”的方式来实现
(3)主要用于从表中取出查询到的行数据
(4)记录类型可以包含一个或多个域,每个域相当于记录类型变量的一个属性.在使用记录变量类型时,实际上是对记录类型变量的属性进行操作.每个域都可以是不同的数据类型,存放不同类型的数据
DECLARE
-- 声明记录类型
TYPE NAMED_RECORE_TYPE IS RECORD(
EMPNO NUMBER(4),
ENAME VARCHAR2(20),
JOB VARCHAR2(20),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(8,2),
COMM NUMBER(8,2),
DEPTNO NUMBER(4)
);
--使用记录类型来声明变量
V_REC NAMED_RECORE_TYPE;
BEGIN
-- 给记录类型的变量赋值,只有类型中声明好的字段,开可以访问该字段
V_REC.EMPNO := 7936;
V_REC.ENAME := '张三';
V_REC.job := '软件工程师';
V_REC.mgr := 7800;
v_reC.hiredate := to_date('1987-12-5','YYYY-MM-DD');
V_REC.SAL := 2000;
V_REC.COMM := 1000;
V_REC.DEPTNO := 10;
dbms_output.put_line('V_REC.EMPNO=' || V_REC.EMPNO || ',V_REC.ENAME='|| V_REC.ENAME || ',v_reC.hiredate='|| TO_CHAR(v_reC.hiredate,'YYYY-MM-DD'));
END;
3、%TYPE与%ROWTYPE
除了象前面那样直接为变量声明一个确定的简单类型或者已经创建好的复合类型外,PL/SQL也支持另外的两种声明变量类型的方法,通红%TYPE和%ROWTYPE属性来声明变量类型
(1) 通过%TYPE属性声明一个变量,变量将遵循下面的类型声明:
一个已经声明过的变量类型
一个数据库中的表的字段定义
通过%TYPE类型声明新变量的类型,实际上就是将参照的变量或表中的字段类型作为新变量的类型,新变量的类型与它所参照的类型完全相同,并且保持同步
(2) 可以作为%TYPE的前缀的可以是
数据库表里面的一列
前面声明的变量名称
(3) PL/SQL在运行程序时确定变量的数据类型和大小
(4) 使用%TYPE,可以声明简单类型,也可以声明表类型
使用%TYPE 属性的好处:
(1) 可能不知道数据库中字段的数据类型
(2) 数据库中字段的数据类型可以在运行时已被改变
(3) 和前面声明过的变量的类型保持一致
-- 除了可以使用已经确定的类型来声明变量职务,还可以使用%type,%rowtype来作为变量的类型
-- 使用%type来声明变量
-- 当我们用%type来声明变量的时候,我们声明的变量是可以是简单类型,也可以是表类型
-- %type的前缀可以是一个前面已经声明过的简单类型的变量(可以是简单类型的变量,也可以是一个复合类型的变量(表类型的变量)),也可以是一个表的字段的名称
DECLARE
V_EMPNO DATE;
V_DEPTNO V_EMPNO%TYPE; -- 用V_EMPNO的类型作为V_DEPTNO的类型
BEGIN
--V_EMPNO := 8000;
--V_DEPTNO := 20;
V_EMPNO := '12-8月-1987';
V_DEPTNO := '5-8月-1987';
DBMS_OUTPUT.put_line('V_EMPNO='||V_EMPNO || ',V_DEPTNO='|| V_DEPTNO);
END;
DECLARE
-- 用emp表的 deptno的类型作为 V_DEPTNO的类型,当emp表的 deptno的类型编号的时候,V_DEPTNO的类型自动跟着变化
V_DEPTNO EMP.ADDR%TYPE;
BEGIN
--V_DEPTNO := '12-5月-1987';
--V_DEPTNO := 30;
V_DEPTNO := '解放路的放到伏交流电';
DBMS_OUTPUT.put_line('V_DEPTNO='|| V_DEPTNO);
END;
DECLARE
-- 声明了一种表类型
TYPE NAMEED_TABLE_TYPE IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
-- 用前面声明的表类型来声明变量
V_TABLE2 NAMEED_TABLE_TYPE;
V_TABLE1 V_TABLE2%TYPE; -- 用V_TABLE2的类型作为V_TABLE1的类型
BEGIN
V_TABLE1(1) := 'Hello1';
V_TABLE1(2) := 'Hello2';
V_TABLE1(3) := 'Hello3';
V_TABLE1(4) := 'Hello1';
V_TABLE1(5) := '工程师';
V_TABLE1(6) := '工程师';
DBMS_OUTPUT.put_line('V_TABLE1(1)=' || V_TABLE1(1) || ',V_TABLE1(2)=' ||
V_TABLE1(2) || ',V_TABLE1(3)=' || V_TABLE1(3) ||
',V_TABLE1(4)=' || V_TABLE1(1) || ',V_TABLE1(5)=' ||
V_TABLE1(5) || ',V_TABLE1(6)=' || V_TABLE1(6));
END;
%ROWTYPE:
(1) 与%TYPE作用类似,用于定义不确定的类型
(2) 变量类型将定义为由数据库的表的字段集合构成的RECORD类型
(3) %ROWTYPE的前缀是数据库的表名(或试图),或者另一个已经定义好的RECORD变量
(4) RECORD中的域,与表的字段的名称,个数,数据类型,以及长度完全相同,可以用来存放从表中取出的一条记录的所有的字段值(select * from 表)
-- %ROWTYPE声明的肯定是记录类型的变量
-- %ROWTYPE的前缀,可以是一个表名,也可以是前面声明的一个记录类型的变量(该变量必须要参照于一个表,而不能是自定义的记录类型)
DECLARE
-- %ROWTYPE的前缀是一个表名
-- 使用%ROWTYPE的时候,Oracle做了两件事情:1.用DEPT表的字段及其类型来声明了一种记录类型;2.用这种记录来声明变量
V_EMP DEPT%ROWTYPE;
BEGIN
V_EMP.DEPTNO := 30;
V_EMP.DNAME := '开发部';
V_EMP.LOC := '北京';
--V_EMP.EMPNO := 7800;
dbms_output.put_line('V_EMP.DEPTNO='||V_EMP.DEPTNO || ',V_EMP.DNAME='||V_EMP.DNAME || ',V_EMP.LOC='|| V_EMP.LOC);
END;
-----------------------------------------------------------------------------
DECLARE
-- V_DEPT是一种记录类型的变量
V_DEPT DEPT%ROWTYPE;
V_EMP V_DEPT%ROWTYPE; -- 用V_DEPT的类型(记录类型)来作为V_EMP的类型,V_EMP也是一种记录类型
BEGIN
V_EMP.DEPTNO := 30;
V_EMP.DNAME := '开发部';
V_EMP.LOC := '北京';
--V_EMP.EMPNO := 7800;
dbms_output.put_line('V_EMP.DEPTNO='||V_EMP.DEPTNO || ',V_EMP.DNAME='||V_EMP.DNAME || ',V_EMP.LOC='|| V_EMP.LOC);
END;
-----------------------------------------------------------------------------
--报错,不可以是自定义变量
DECLARE
TYPE NAMED_RECORE_TYPE IS RECORD(
EMPNO NUMBER(4),
ENAME VARCHAR2(20),
JOB VARCHAR2(20),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(8,2),
COMM NUMBER(8,2),
DEPTNO NUMBER(4)
);
V_DEPT NAMED_RECORE_TYPE;
V_EMP V_DEPT%ROWTYPE;
BEGIN
/*
V_EMP.DEPTNO := 30;
V_EMP.DNAME := '开发部';
V_EMP.LOC := '北京';
--V_EMP.EMPNO := 7800;
dbms_output.put_line('V_EMP.DEPTNO='||V_EMP.DEPTNO || ',V_EMP.DNAME='||V_EMP.DNAME || ',V_EMP.LOC='|| V_EMP.LOC);
*/
dbms_output.put_line('Hello_world');
END;
%ROWTYPE 属性:优点
(1)、数据库中表字段的数据类型和数目可能不知道
(2)、数据库中表字段的个数和数据类型会在运行中改变
1、语句可以写在多行,就象SQL语句一样
2、各个关键字,字段名称等,通过空格分隔
3、每条语句必须通过分号结束,包括PL/SQL结束部分的END关键字后面也需要加分号
4、标识符的规定:
(1) 最多可以包含30个字符
(2) 不能包含保留字,若有使用双引号括起来
(3) 必须以字母字符开始
(4) 不能与数据库的表或者列名称相同
5、在PL/SQL程序中出现的字符和日期必须用单引号括起来
6、数字可以是简单值或科学计数法表示
V_SAL NUMBER(4) := 2000;
V_YEAR NUMBER(4) := V_SAL * 12;
7、在PL/SQL中也要养成添加注释的习惯,注释可以是
/* 和*/之间的多行注释
单行注释,以 – 开始
8、使用“:=”作为赋值符号,而不是“=”
1、PL/SQL程序也叫做PL/SQL程序块,在程序块中可以嵌套另一个程序块,外部的程序块叫做“父块”或“外部块”,嵌套的块叫“子块”或“嵌套块”
2、只要是允许执行语句的地方,就可以使用嵌套PL/SQL 块
3、嵌套块也被当作一个语句
4、异常部分也可以包含嵌套块,嵌套块也可以包括异常部分
5、应用对象的程序对象的作用域指的是可以范围
6、标识符可见的范围:
子块可以向上查看父块的标识符
父块不能向下查看到子块的标识符
-- 只要是能出现非声明性的SQL语句的地方(在begin和exception部分),都可以出现嵌套块
-- 嵌套块本身就被当作一个SQL语句来执行
-- 外面的块被称为父块,嵌套块被称为子块
-- 子块可以看到父块的内容,而父块不能看到子块的内容
DECLARE
BEGIN
---------------------------------
DECLARE
BEGIN
EXCEPTION
END;
---------------------------------
EXCEPTION
---------------------------------
DECLARE
BEGIN
EXCEPTION
END;
---------------------------------
END;
DECLARE
V_WEIGHT NUMBER(3) := 100;
BEGIN
----------------------------------------------
DECLARE
V_WEIGHT NUMBER(3) := 200;
BEGIN
V_WEIGHT := V_WEIGHT + 1 ;
DBMS_OUTPUT.put_line('在嵌套块中:V_WEIGHT='||V_WEIGHT); -- 101
END;
----------------------------------------------
V_WEIGHT := V_WEIGHT + 1 ;
DBMS_OUTPUT.put_line('在嵌套块外:V_WEIGHT='||V_WEIGHT); -- 102
END;
在嵌套块中:V_WEIGHT=201
在嵌套块外:V_WEIGHT=101
-- 在PLSQL中使用函数和直接在Oracle中使用函数没有区别
DECLARE
V_DATE DATE := TO_DATE('1987-12-8','YYYY-MM-DD');
V_NAME VARCHAR2(10) := 'HelloWorld';
BEGIN
DBMS_OUTPUT.put_line('V_DATE=' || TO_CHAR(V_DATE,'YYYY-MM-DD') || ',字符长度是:' || LENGTH(V_NAME));
END;
V_DATE=1987-12-08,字符长度是:10
declare
v_1 varchar2(20);
begin
v_1 := USER||': '||TO_CHAR(SYSDATE,'YYYY-MM-DD');
-- USER会返回当前登录的用户的名称, SYSDATE是日期型的数据,Oracle会自动的把Date类型转换为字符性
--v_1 := USER || ': ' || SYSDATE;
dbms_output.put_line(v_1);
end;
SCOTT: 2019-10-23
-- 在PL/SQL中执行SELECT语句,用来把查询的数据赋值给变量
-- SELECT语句只能返回一条记录(返回0条多条都会报错),并且要配合使用INTO
SELECT EMPNO,ENAME FROM EMP WHERE EMPNO = 7369;
DECLARE
V_EMPNO EMP.EMPNO%TYPE;
V_ENME EMP.ENAME%TYPE;
V_JOB EMP.JOB%TYPE;
BEGIN
-- 查询列表和变量必须要匹配
SELECT EMPNO,ENAME,JOB INTO V_EMPNO,V_ENME,V_JOB FROM EMP WHERE EMPNO = 7369;
DBMS_OUTPUT.put_line('V_EMPNO='||V_EMPNO || ',V_ENME='|| V_ENME || ',V_JOB=' || V_JOB);
END;
-- 用记录类型的变量和SELECT * 搭配使用
SELECT * FROM EMP WHERE DEPTNO=10;
DECLARE
V_EMP EMP%ROWTYPE;
BEGIN
SELECT * INTO V_EMP FROM EMP WHERE DEPTNO=10;
DBMS_OUTPUT.put_line(V_EMP.EMPNO || ',' || V_EMP.ENAME || ',' ||
V_EMP.JOB || ',' || V_EMP.MGR || ',' ||
V_EMP.HIREDATE || ',' || NVL( V_EMP.SAL,0) || ',' ||
NVL(V_EMP.COMM,0) || ',' || V_EMP.DEPTNO);
END;
-- 在PL/SQL中使用组函数的时候,可以使用;但是要保证查询语句只能返回一条记录
SELECT DEPTNO ,MAX(SAL) MAXSAL,MIN(SAL)MINSAL
FROM EMP
GROUP BY DEPTNO
HAVING MAX(SAL) > 3000;
DECLARE
V_DEPTNO NUMBER(4);
V_MAXSAL NUMBER(8,2);
V_MINSAL NUMBER(8,2);
BEGIN
SELECT DEPTNO ,MAX(SAL) MAXSAL,MIN(SAL)MINSAL INTO V_DEPTNO,V_MAXSAL,V_MINSAL
FROM EMP
GROUP BY DEPTNO
HAVING MAX(SAL) > 3000;
DBMS_OUTPUT.put_line('V_DEPTNO=='||V_DEPTNO || ',V_MAXSAL='||V_MAXSAL || ',V_MINSAL='||V_MINSAL);
END;
V_DEPTNO==10,V_MAXSAL=5000,V_MINSAL=1300
-- 在PL/SQL中执行DML语句,事务控制语句,和在Oracle中执行没有任何区别
BEGIN
INSERT INTO EMP VALUES (8000,'张1','销售员',7902,'12-8月-1986',2000,1000,10);
UPDATE EMP SET JOB= 'MANAGER' ,SAL = 2600 WHERE EMPNO = 7369;
DELETE FROM DEPT WHERE DEPTNO = 40;
--COMMIT;
--ROLLBACK;
END;
SELECT * FROM EMP;
SELECT * FROM DEPT;
-- 在PL/SQL中执行DDL,DCL要使用 EXECUTE IMMEDIATE
CREATE TABLE USERS (USERID NUMBER(4) PRIMARY KEY,USEERNAME VARCHAR2(20),SEX CHAR (2) CHECK (SEX IN ('男','女')) )
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE USERS (ID NUMBER(4) PRIMARY KEY,NAME VARCHAR2(20),SEX CHAR (2) )';
END;
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE USERS (USERID NUMBER(4) PRIMARY KEY,USEERNAME VARCHAR2(20),SEX CHAR (2) CHECK (SEX IN (''男'',''女'')) )';
END;
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE USERS';
END;
-- 在PLSQL中使用IF ELSIF ELSE
-- 根据职务,现有的工资给7369 涨工资,
SELECT JOB ,SAL FROM EMP WHERE EMPNO = 7369
DECLARE
V_JOB EMP.JOB%TYPE;
V_SAL EMP.SAL%TYPE;
V_ADDSAL V_SAL%TYPE;
BEGIN
SELECT JOB ,SAL INTO V_JOB,V_SAL FROM EMP WHERE EMPNO = 7369;
IF ( V_JOB = 'CLERK') THEN
V_ADDSAL := V_SAL * 1.2;
ELSIF (V_JOB = 'SALESMAN') THEN
V_ADDSAL := V_SAL * 1.5;
ELSIF (V_JOB = 'PRESIDENT') THEN
V_ADDSAL := V_SAL * 1.7;
ELSIF (V_JOB = 'MANAGER') THEN
V_ADDSAL := V_SAL * 1.8;
ELSE
V_ADDSAL := V_SAL * 2.0;
END IF;
UPDATE EMP SET SAL = V_ADDSAL WHERE EMPNO = 7369;
COMMIT;
END;
SELECT DISTINCT JOB FROM EMP
-- LOOP循环
-- 循环的四个条件:1.初始条件;2.循环条件;3.循环体;4.迭代条件
DECLARE
V_COUNT NUMBER(3) := 1; -- 初始条件
BEGIN
LOOP
DBMS_OUTPUT.put_line('V_COUNT=' || V_COUNT); -- 循环体
V_COUNT := V_COUNT +1; -- 迭代条件
EXIT WHEN V_COUNT > 10; -- .循环条件
END LOOP;
END;
SELECT * FROM USERS;
-- 利用loop循环,向users表插入100条数据,如果编号是奇数.性别为男.如果编号是偶数,性别为女
DECLARE
V_SEX CHAR(2);
V_COUTN NUMBER(10) := 1;
V_NAME VARCHAR2(20);
BEGIN
LOOP
IF (MOD(V_COUTN, 2) = 0) THEN
V_SEX := '女';
ELSE
V_SEX := '男';
END IF;
V_NAME := '张' || V_COUTN;
INSERT INTO USERS VALUES (V_COUTN, V_NAME, V_SEX);
V_COUTN := V_COUTN + 1;
EXIT WHEN V_COUTN > 10000;
END LOOP;
COMMIT;
END;
TRUNCATE TABLE USERS;
SELECT * FROM USERS;
-- WHIL循环
DECLARE
V_COUNT NUMBER(3) := 1; -- 初始条件
BEGIN
WHILE (V_COUNT <= 10) LOOP -- 循环条件
DBMS_OUTPUT.put_line('V_COUNT=' || V_COUNT); -- 循环体
V_COUNT := V_COUNT + 1; -- 迭代条件
END LOOP;
END;
DECLARE
V_COUNT NUMBER(3) := 1; -- 初始条件
V_SEX CHAR(2);
V_NAME VARCHAR2(10);
BEGIN
WHILE (V_COUNT <= 100) LOOP -- 循环条件
IF (MOD (V_COUNT,2) = 0) THEN
V_SEX := '女';
ELSE
V_SEX := '男';
END IF;
V_NAME := '张' || V_COUNT;
INSERT INTO USERS VALUES (V_COUNT,V_NAME,V_SEX);
V_COUNT := V_COUNT +1;
END LOOP;
COMMIT;
END;
使用FOR循环,循环执行指定的次数
FOR index in [REVERSE]
lower_bound..upper_bound LOOP
statement1;
. . .
END LOOP;
REVERSE是反转的意思,正常的循环计数器从
小到大,使用REVERSE将使计数器从大到小递减
-- FOR循环.在使用FOR循环的时候,由Oracle来维护计数器
DECLARE
V_SEX CHAR(2);
V_NAME VARCHAR2(10);
BEGIN
-- Oracle会自动的声明计数器,会自动的进行计数器的迭代
FOR V_COUNT IN REVERSE 1..100 LOOP
IF (MOD (V_COUNT,2) = 0) THEN
V_SEX := '女';
ELSE
V_SEX := '男';
END IF;
V_NAME := '张' || V_COUNT;
INSERT INTO USERS VALUES (V_COUNT,V_NAME,V_SEX);
END LOOP;
COMMIT;
END;