PL / SQL教程

PL / SQL - 快速指南

 


PL / SQL - 概述

PL / SQL编程语言是由Oracle公司在20世纪80年代后期开发的,作为SQL和Oracle关系数据库的过程扩展语言。以下是关于PL / SQL的一些值得注意的事实 -

  • PL / SQL是一种完全可移植的高性能事务处理语言。

  • PL / SQL提供内置,解释和OS独立的编程环境。

  • PL / SQL也可以直接从命令行SQL * Plus接口调用。

  • 也可以从外部编程语言调用到数据库进行直接调用。

  • PL / SQL的一般语法基于ADA和Pascal编程语言。

  • 除了Oracle之外,PL / SQL还可以在TimesTen内存数据库IBM DB2中使用

PL / SQL的特点

PL / SQL具有以下功能 -

  • PL / SQL与SQL紧密集成。
  • 它提供广泛的错误检查。
  • 它提供了许多数据类型。
  • 它提供了各种编程结构。
  • 它通过功能和程序支持结构化编程。
  • 它支持面向对象的编程。
  • 它支持Web应用程序和服务器页面的开发。

PL / SQL的优点

PL / SQL具有以下优点 -

  • SQL是标准的数据库语言,PL / SQL与SQL强大集成。PL / SQL支持静态和动态SQL。Static SQL支持PL / SQL块的DML操作和事务控制。在Dynamic SQL中,SQL允许在PL / SQL块中嵌入DDL语句。

  • PL / SQL允许一次将整个语句块发送到数据库。这可以减少网络流量并为应用程序提供高性能。

  • PL / SQL为程序员提供了高生产率,因为它可以查询,转换和更新数据库中的数据。

  • PL / SQL通过强大的功能节省了设计和调试的时间,例如异常处理,封装,数据隐藏和面向对象的数据类型。

  • 用PL / SQL编写的应用程序是完全可移植的。

  • PL / SQL提供高安全级别。

  • PL / SQL提供对预定义SQL包的访问。

  • PL / SQL为面向对象编程提供支持。

  • PL / SQL为开发Web应用程序和服务器页面提供支持。

PL / SQL - 环境设置

在本章中,我们将讨论PL / SQL的环境设置。PL / SQL不是一种独立的编程语言; 它是Oracle编程环境中的一个工具。SQL * Plus是一个交互式工具,允许您在命令提示符下键入SQL和PL / SQL语句。然后将这些命令发送到数据库进行处理。处理完语句后,结果将被发回并显示在屏幕上。

要运行PL / SQL程序,您应该在计算机中安装Oracle RDBMS Server。这将负责SQL命令的执行。Oracle RDBMS的最新版本是11g。您可以从以下链接下载Oracle 11g的试用版 -

下载Oracle 11g Express Edition

您必须根据您的操作系统下载32位或64位版本的安装。通常有两个文件。我们已经下载了64位版本。您还将在操作系统上使用类似的步骤,无论是Linux还是Solaris。

  • win64_11gR2_database_1of2.zip

  • win64_11gR2_database_2of2.zip

下载上述两个文件后,您需要将它们解压缩到一个目录数据库中,然后您将找到以下子目录 -

Oracle Sub Directries

步骤1

现在让我们使用安装文件启动Oracle Database Installer。以下是第一个屏幕。您可以提供您的电子邮件ID并选中复选框,如以下屏幕截图所示。单击“ 下一步”按钮。

Oracle安装1

第2步

您将被引导至以下屏幕; 取消选中该复选框,然后单击继续按钮继续。

Oracle安装错误

第3步

只需使用单选按钮选择第一个选项“ 创建和配置数据库 ”,然后单击“ 下一步”按钮继续。

Oracle安装2

第4步

我们假设您正在安装Oracle,以实现学习的基本目的,并将其安装在PC或笔记本电脑上。因此,选择“ 桌面类”选项,然后单击“ 下一步”按钮继续。

Oracle安装3

第5步

提供一个位置,您将在其中安装Oracle Server。只需修改Oracle Base,其他位置就会自动设置。您还必须提供密码; 这将由系统DBA使用。提供所需信息后,单击“ 下一步”按钮继续。

Oracle安装4

第6步

再次单击“ 下一步”按钮继续。

Oracle安装5

第7步

单击“ 完成”按钮继续; 这将启动实际的服务器安装。

Oracle安装6

第8步

这将需要一些时间,直到Oracle开始执行所需的配置。

Oracle安装7

第9步

在这里,Oracle安装将复制所需的配置文件。这应该花一点时间 -

Oracle配置

第10步

复制数据库文件后,您将看到以下对话框。只需单击“ 确定”按钮即可。

Oracle配置

第11步

安装后,您将拥有以下最终窗口。

Oracle Install 8

最后一步

现在是时候验证您的安装了。在命令提示符下,如果您使用Windows,请使用以下命令 -

<span style="color:#313131">sqlplus "/ as sysdba"
</span>

你应该在SQL提示符下编写PL / SQL命令和脚本 -

PL / SQL命令提示符

文本编辑器

从命令提示符运行大型程序可能会让您无意中失去一些工作。始终建议使用命令文件。要使用命令文件 -

  • 在文本编辑器中键入代码,如记事本,记事本+EditPlus等。

  • 在主目录中使用.sql扩展名保存文件。

  • 从您创建PL / SQL文件的目录中启动SQL * Plus命令提示符

  • 在SQL * Plus命令提示符下键入@file_name以执行您的程序。

如果您没有使用文件来执行PL / SQL脚本,那么只需复制您的PL / SQL代码并右键单击显示SQL提示的黑色窗口; 使用粘贴选项在命令提示符处粘贴完整代码。最后,只需按Enter键即可执行代码(如果尚未执行)。

PL / SQL - 基本语法

在本章中,我们将讨论PL / SQL的基本语法,它是一种块结构语言; 这意味着PL / SQL程序被划分并写入逻辑代码块。每个街区由三个子部分组成 -

 

 

  •  

PL / SQL - 快速指南


 


PL / SQL - 概述

PL / SQL编程语言是由Oracle公司在20世纪80年代后期开发的,作为SQL和Oracle关系数据库的过程扩展语言。以下是关于PL / SQL的一些值得注意的事实 -

  • PL / SQL是一种完全可移植的高性能事务处理语言。

  • PL / SQL提供内置,解释和OS独立的编程环境。

  • PL / SQL也可以直接从命令行SQL * Plus接口调用。

  • 也可以从外部编程语言调用到数据库进行直接调用。

  • PL / SQL的一般语法基于ADA和Pascal编程语言。

  • 除了Oracle之外,PL / SQL还可以在TimesTen内存数据库IBM DB2中使用

PL / SQL的特点

PL / SQL具有以下功能 -

  • PL / SQL与SQL紧密集成。
  • 它提供广泛的错误检查。
  • 它提供了许多数据类型。
  • 它提供了各种编程结构。
  • 它通过功能和程序支持结构化编程。
  • 它支持面向对象的编程。
  • 它支持Web应用程序和服务器页面的开发。

PL / SQL的优点

PL / SQL具有以下优点 -

  • SQL是标准的数据库语言,PL / SQL与SQL强大集成。PL / SQL支持静态和动态SQL。Static SQL支持PL / SQL块的DML操作和事务控制。在Dynamic SQL中,SQL允许在PL / SQL块中嵌入DDL语句。

  • PL / SQL允许一次将整个语句块发送到数据库。这可以减少网络流量并为应用程序提供高性能。

  • PL / SQL为程序员提供了高生产率,因为它可以查询,转换和更新数据库中的数据。

  • PL / SQL通过强大的功能节省了设计和调试的时间,例如异常处理,封装,数据隐藏和面向对象的数据类型。

  • 用PL / SQL编写的应用程序是完全可移植的。

  • PL / SQL提供高安全级别。

  • PL / SQL提供对预定义SQL包的访问。

  • PL / SQL为面向对象编程提供支持。

  • PL / SQL为开发Web应用程序和服务器页面提供支持。

PL / SQL - 环境设置

在本章中,我们将讨论PL / SQL的环境设置。PL / SQL不是一种独立的编程语言; 它是Oracle编程环境中的一个工具。SQL * Plus是一个交互式工具,允许您在命令提示符下键入SQL和PL / SQL语句。然后将这些命令发送到数据库进行处理。处理完语句后,结果将被发回并显示在屏幕上。

要运行PL / SQL程序,您应该在计算机中安装Oracle RDBMS Server。这将负责SQL命令的执行。Oracle RDBMS的最新版本是11g。您可以从以下链接下载Oracle 11g的试用版 -

下载Oracle 11g Express Edition

您必须根据您的操作系统下载32位或64位版本的安装。通常有两个文件。我们已经下载了64位版本。您还将在操作系统上使用类似的步骤,无论是Linux还是Solaris。

  • win64_11gR2_database_1of2.zip

  • win64_11gR2_database_2of2.zip

下载上述两个文件后,您需要将它们解压缩到一个目录数据库中,然后您将找到以下子目录 -

Oracle Sub Directries

步骤1

现在让我们使用安装文件启动Oracle Database Installer。以下是第一个屏幕。您可以提供您的电子邮件ID并选中复选框,如以下屏幕截图所示。单击“ 下一步”按钮。

Oracle安装1

第2步

您将被引导至以下屏幕; 取消选中该复选框,然后单击继续按钮继续。

Oracle安装错误

第3步

只需使用单选按钮选择第一个选项“ 创建和配置数据库 ”,然后单击“ 下一步”按钮继续。

Oracle安装2

第4步

我们假设您正在安装Oracle,以实现学习的基本目的,并将其安装在PC或笔记本电脑上。因此,选择“ 桌面类”选项,然后单击“ 下一步”按钮继续。

Oracle安装3

第5步

提供一个位置,您将在其中安装Oracle Server。只需修改Oracle Base,其他位置就会自动设置。您还必须提供密码; 这将由系统DBA使用。提供所需信息后,单击“ 下一步”按钮继续。

Oracle安装4

第6步

再次单击“ 下一步”按钮继续。

Oracle安装5

第7步

单击“ 完成”按钮继续; 这将启动实际的服务器安装。

Oracle安装6

第8步

这将需要一些时间,直到Oracle开始执行所需的配置。

Oracle安装7

第9步

在这里,Oracle安装将复制所需的配置文件。这应该花一点时间 -

Oracle配置

第10步

复制数据库文件后,您将看到以下对话框。只需单击“ 确定”按钮即可。

Oracle配置

第11步

安装后,您将拥有以下最终窗口。

Oracle Install 8

最后一步

现在是时候验证您的安装了。在命令提示符下,如果您使用Windows,请使用以下命令 -

<span style="color:#313131">sqlplus "/ as sysdba"
</span>

你应该在SQL提示符下编写PL / SQL命令和脚本 -

PL / SQL命令提示符

文本编辑器

从命令提示符运行大型程序可能会让您无意中失去一些工作。始终建议使用命令文件。要使用命令文件 -

  • 在文本编辑器中键入代码,如记事本,记事本+EditPlus等。

  • 在主目录中使用.sql扩展名保存文件。

  • 从您创建PL / SQL文件的目录中启动SQL * Plus命令提示符

  • 在SQL * Plus命令提示符下键入@file_name以执行您的程序。

如果您没有使用文件来执行PL / SQL脚本,那么只需复制您的PL / SQL代码并右键单击显示SQL提示的黑色窗口; 使用粘贴选项在命令提示符处粘贴完整代码。最后,只需按Enter键即可执行代码(如果尚未执行)。

PL / SQL - 基本语法

在本章中,我们将讨论PL / SQL的基本语法,它是一种块结构语言; 这意味着PL / SQL程序被划分并写入逻辑代码块。每个街区由三个子部分组成 -

S.No 章节和描述
1

声明

本节以关键字DECLARE开头。它是一个可选部分,定义了程序中使用的所有变量,游标,子程序和其他元素。

2

可执行命令

此部分包含在关键字BEGINEND之间,它是必填部分。它由程序的可执行PL / SQL语句组成。它应该至少有一个可执行的代码行,它可能只是一个NULL命令,表示不应该执行任何操作。

3

异常处理

本节以关键字EXCEPTION开头。此可选部分包含处理程序错误的异常

每个PL / SQL语句都以分号(;)结尾。PL / SQL块可以使用BEGINEND嵌套在其他PL / SQL块中。以下是PL / SQL块的基本结构 -

<span style="color:#313131">DECLARE 
   <declarations section> 
BEGIN 
   <executable command(s)>
EXCEPTION 
   <exception handling> 
END;
</span>

'Hello World'示例

<span style="color:#313131">DECLARE 
   message  varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">):=</span> <span style="color:#008800">'Hello, World!'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>message<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

结束; line表示PL / SQL块的结尾。要从SQL命令行运行代码,您可能需要在代码的最后一行之后的第一个空白行的开头键入/。当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Hello World  

PL/SQL procedure successfully completed.
</span>

PL / SQL标识符

PL / SQL标识符是常量,变量,异常,过程,游标和保留字。标识符由一个字母组成,可选地后跟更多的字母,数字,美元符号,下划线和数字符号,不得超过30个字符。

默认情况下,标识符不区分大小写。因此,您可以使用整数INTEGER来表示数值。您不能使用保留关键字作为标识符。

PL / SQL分隔符

分隔符是具有特殊含义的符号。以下是PL / SQL中的分隔符列表 -

分隔符 描述
+, - ,*,/ 加法,减法/否定,乘法,除法
属性指标
字符串分隔符
组件选择器
(,) 表达式或列表分隔符
主变量指标
项目分隔符
带引号的标识符分隔符
= 关系运算符
@ 远程访问指示器
; 声明终止符
:= 分配操作员
=> 协会运营商
|| 连接运算符
** 指数运算符
<<,>> 标签分隔符(开始和结束)
/ *,* / 多行注释分隔符(开头和结尾)
- 单行评论指标
.. 范围运算符
<,>,<=,> = 关系运算符
<>,'=,〜=,^ = 不等版本的NOT EQUAL

PL / SQL评论

程序注释是可以包含在您编写的PL / SQL代码中的解释性语句,可以帮助任何人阅读其源代码。所有编程语言都允许某种形式的注释。

PL / SQL支持单行和多行注释。PL / SQL编译器会忽略任何注释中可用的所有字符。PL / SQL单行注释以分隔符开头 - (双连字符),多行注释由/ *和* /括起。

<span style="color:#313131">DECLARE 
   <span style="color:#666600">--</span> variable declaration 
   message  varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">):=</span> <span style="color:#008800">'Hello, World!'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#880000">/* 
   *  PL/SQL executable statement(s) 
   */</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>message<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131"><span style="color:#7f0055">Hello</span> <span style="color:#7f0055">World</span>

PL<span style="color:#666600">/</span>SQL procedure successfully completed<span style="color:#666600">.</span></span>

PL / SQL程序单元

PL / SQL单元是以下任何一种 -

  • PL / SQL块
  • 功能
  • 包体
  • 程序
  • 触发
  • 类型
  • 输入正文

这些单元中的每一个都将在以下章节中讨论。

PL / SQL - 数据类型

在本章中,我们将讨论PL / SQL中的数据类型。PL / SQL变量,常量和参数必须具有有效的数据类型,该类型指定存储格式,约束和有效的值范围。我们将在本章重点介绍SCALARLOB数据类型。其他两种数据类型将在其他章节中介绍。

S.No 类别和描述
1

纯量

单个值,没有内部组件,例如NUMBER,DATEBOOLEAN

2

大对象(LOB)

指向与其他数据项分开存储的大对象的指针,例如文本,图形图像,视频剪辑和声音波形。

3

综合

具有可单独访问的内部组件的数据项。例如,集合和记录。

4

参考

指向其他数据项的指针。

PL / SQL标量数据类型和子类型

PL / SQL标量数据类型和子类型属于以下类别 -

S.No 日期类型和描述
1

数字

执行算术运算的数值。

2

字符

表示单个字符或字符串的字母数字值。

3

布尔

执行逻辑操作的逻辑值。

4

约会时间

日期和时间。

PL / SQL提供了数据类型的子类型。例如,数据类型NUMBER具有名为INTEGER的子类型。您可以使用PL / SQL程序中的子类型使数据类型与其他程序中的数据类型兼容,同时将PL / SQL代码嵌入到另一个程序(如Java程序)中。

PL / SQL数字数据类型和子类型

下表列出了PL / SQL预定义数值数据类型及其子类型 -

S.No 数据类型和描述
1

PLS_INTEGER

有符号整数,范围为-2,147,483,648到2,147,483,647,以32位表示

2

BINARY_INTEGER

有符号整数,范围为-2,147,483,648到2,147,483,647,以32位表示

3

BINARY_FLOAT

单精度IEEE 754格式浮点数

4

BINARY_DOUBLE

双精度IEEE 754格式浮点数

NUMBER(预定,比例)

定点或浮点数,绝对值范围为1E-130至(但不包括)1.0E126。NUMBER变量也可以表示0

6

DEC(prec,scale)

ANSI特定定点类型,最大精度为38位十进制数

7

DECIMAL(prec,scale)

IBM特定定点类型,最大精度为38位十进制数

8

NUMERIC(pre,secale)

浮点类型,最大精度为38位十进制数

9

双精度

ANSI特定浮点类型,最大精度为126个二进制数字(约38个十进制数字)

10

浮动

ANSI和IBM特定的浮点类型,最大精度为126个二进制数字(约38个十进制数字)

11

INT

ANSI特定整数类型,最大精度为38位十进制数

12

整数

ANSI和IBM特定的整数类型,最大精度为38位十进制数

13

SMALLINT

ANSI和IBM特定的整数类型,最大精度为38位十进制数

14

真实

浮点类型,最大精度为63位二进制数字(大约18位十进制数字)

以下是有效的声明 -

<span style="color:#313131">DECLARE 
   num1 INTEGER<span style="color:#666600">;</span> 
   num2 REAL<span style="color:#666600">;</span> 
   num3 DOUBLE PRECISION<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#000088">null</span><span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

编译并执行上述代码时,会产生以下结果 -

<span style="color:#313131">PL<span style="color:#666600">/</span>SQL procedure successfully completed </span>

PL / SQL字符数据类型和子类型

以下是PL / SQL预定义字符数据类型及其子类型的详细信息 -

S.No 数据类型和描述
1

CHAR

固定长度的字符串,最大大小为32,767字节

2

VARCHAR2

可变长度字符串,最大大小为32,767字节

3

生的

可变长度二进制或字节字符串,最大大小为32,767字节,不由PL / SQL解释

4

NCHAR

固定长度的国家字符串,最大大小为32,767字节

NVARCHAR2

可变长度的国家字符串,最大大小为32,767字节

6

可变长度字符串,最大大小为32,760字节

7

LONG RAW

可变长度二进制或字节字符串,最大大小为32,760字节,不由PL / SQL解释

8

ROWID

物理行标识符,普通表中行的地址

9

UROWID

通用行标识符(物理,逻辑或外部行标识符)

PL / SQL布尔数据类型

BOOLEAN了在逻辑操作中使用的数据类型存储的逻辑值。逻辑值是布尔值TRUEFALSE以及值NULL

但是,SQL没有与BOOLEAN等效的数据类型。因此,布尔值不能用于 -

  • SQL语句
  • 内置SQL函数(如TO_CHAR
  • 从SQL语句调用的PL / SQL函数

PL / SQL日期时间和间隔类型

DATE数据类型用于存储固定长度日期时间,其中包括从午夜天的以秒计的时间。有效日期为公元前4712年1月1日至公元9999年12月31日。

默认日期格式由Oracle初始化参数NLS_DATE_FORMAT设置。例如,默认值可能是“DD-MON-YY”,其中包括月份日期的两位数字,月份名称的缩写以及年份的最后两位数字。例如,01-OCT-12。

每个日期包括世纪,年,月,日,小时,分钟和秒。下表显示了每个字段的有效值 -

字段名称 有效的日期时间值 有效间隔值
-4712至9999(不包括0年) 任何非零整数
01至12 0到11
01到31(根据区域设置的日历规则,受MONTH和YEAR的值限制) 任何非零整数
小时 00至23 0到23
分钟 00至59 0到59
第二 00至59.9(n),其中9(n)是时间分数秒的精度 0到59.9(n),其中9(n)是区间小数秒的精度
TIMEZONE_HOUR -12至14(范围适应夏令时变化) 不适用
TIMEZONE_MINUTE 00至59 不适用
TIMEZONE_REGION 在动态性能视图中找到V $ TIMEZONE_NAMES 不适用
TIMEZONE_ABBR 在动态性能视图中找到V $ TIMEZONE_NAMES 不适用

PL / SQL大对象(LOB)数据类型

大对象(LOB)数据类型指的是大数据项,例如文本,图形图像,视频剪辑和声音波形。LOB数据类型允许对此数据进行高效,随机,分段访问。以下是预定义的PL / SQL LOB数据类型 -

数据类型 描述 尺寸
BFILE 用于在数据库外部的操作系统文件中存储大型二进制对象。 取决于系统。不能超过4千兆字节(GB)。
BLOB 用于在数据库中存储大型二进制对象。 8到128太字节(TB)
CLOB 用于在数据库中存储大块字符数据。 8到128 TB
NCLOB 用于在数据库中存储大块NCHAR数据。 8到128 TB

PL / SQL用户定义的子类型

子类型是另一种数据类型的子集,称为其基本类型。子类型与其基本类型具有相同的有效操作,但只有其有效值的子集。

PL / SQL在包STANDARD中预定义了几个子类型。例如,PL / SQL预定义子类型CHARACTERINTEGER如下 -

<span style="color:#313131">SUBTYPE CHARACTER IS CHAR; 
SUBTYPE INTEGER IS NUMBER(38,0);
</span>

您可以定义和使用自己的子类型。以下程序说明了如何定义和使用用户定义的子类型 -

<span style="color:#313131">DECLARE 
   SUBTYPE name IS <span style="color:#000088">char</span><span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">);</span> 
   SUBTYPE message IS varchar2<span style="color:#666600">(</span><span style="color:#006666">100</span><span style="color:#666600">);</span> 
   salutation name<span style="color:#666600">;</span> 
   greetings message<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   salutation <span style="color:#666600">:=</span> <span style="color:#008800">'Reader '</span><span style="color:#666600">;</span> 
   greetings <span style="color:#666600">:=</span> <span style="color:#008800">'Welcome to the World of PL/SQL'</span><span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Hello '</span> <span style="color:#666600">||</span> salutation <span style="color:#666600">||</span> greetings<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Hello Reader Welcome to the World of PL/SQL 
 
PL/SQL procedure successfully completed. 
</span>

PL / SQL中的NULL

PL / SQL NULL值表示缺失未知数据,它们不是整数,字符或任何其他特定数据类型。请注意,NULL与空数据字符串或空字符值'\ 0'不同。可以指定null,但不能将其等同于任何内容,包括其自身。

PL / SQL - 变量

在本章中,我们将讨论Pl / SQL中的变量。变量只不过是我们的程序可以操作的存储区域的名称。PL / SQL中的每个变量都有一个特定的数据类型,它决定了变量内存的大小和布局; 可存储在该内存中的值范围以及可应用于该变量的操作集。

PL / SQL变量的名称由一个字母组成,可选地后跟更多的字母,数字,美元符号,下划线和数字符号,不应超过30个字符。默认情况下,变量名称不区分大小写。您不能将保留的PL / SQL关键字用作变量名。

PL / SQL编程语言允许定义各种类型的变量,例如日期时间数据类型,记录,集合等,我们将在后续章节中介绍。在本章中,我们只研究基本变量类型。

PL / SQL中的变量声明

PL / SQL变量必须在声明部分或包中声明为全局变量。声明变量时,PL / SQL为变量的值分配内存,存储位置由变量名称标识。

声明变量的语法是 -

<span style="color:#313131">variable_name [CONSTANT] datatype [NOT NULL] [:= | DEFAULT initial_value] 
</span>

其中,variable_name是PL / SQL中的有效标识符,数据类型必须是有效的PL / SQL数据类型或我们已在上一章中讨论过的任何用户定义的数据类型。一些有效的变量声明及其定义如下所示 -

<span style="color:#313131">sales number(10, 2); 
pi CONSTANT double precision := 3.1415; 
name varchar2(25); 
address varchar2(100);
</span>

当您使用数据类型提供大小,比例或精度限制时,它称为约束声明。约束声明比无约束声明需要更少的内存。例如 -

<span style="color:#313131">sales number(10, 2); 
name varchar2(25); 
address varchar2(100); 
</span>

在PL / SQL中初始化变量

每当您声明一个变量时,PL / SQL都会为其指定一个默认值NULL。如果要使用除NULL值以外的值初始化变量,则可以在声明期间使用以下任一方法执行此操作 -

  • DEFAULT关键字

  • 赋值运算符

例如 -

<span style="color:#313131">counter binary_integer := 0; 
greetings varchar2(20) DEFAULT 'Have a Good Day';
</span>

您还可以使用NOT NULL约束指定变量不应具有NULL值。如果使用NOT NULL约束,则必须为该变量显式指定初始值。

如果正确初始化变量是一个很好的编程习惯,否则程序会产生意想不到的结果。尝试使用以下示例,该示例使用各种类型的变量 -

<span style="color:#313131">DECLARE 
   a integer <span style="color:#666600">:=</span> <span style="color:#006666">10</span><span style="color:#666600">;</span> 
   b integer <span style="color:#666600">:=</span> <span style="color:#006666">20</span><span style="color:#666600">;</span> 
   c integer<span style="color:#666600">;</span> 
   f real<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   c <span style="color:#666600">:=</span> a <span style="color:#666600">+</span> b<span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Value of c: '</span> <span style="color:#666600">||</span> c<span style="color:#666600">);</span> 
   f <span style="color:#666600">:=</span> <span style="color:#006666">70.0</span><span style="color:#666600">/</span><span style="color:#006666">3.0</span><span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Value of f: '</span> <span style="color:#666600">||</span> f<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

执行上述代码时,会产生以下结果 -

<span style="color:#313131">Value of c: 30 
Value of f: 23.333333333333333333  

PL/SQL procedure successfully completed. 
</span>

PL / SQL中的变量范围

PL / SQL允许嵌套块,即每个程序块可以包含另一个内部块。如果在内部块中声明变量,则外部块无法访问它。但是,如果声明了一个变量并且外部块可以访问它,那么所有嵌套的内部块也可以访问它。变量范围有两种类型 -

  • 局部变量 - 在内部块中声明且外部块无法访问的变量。

  • 全局变量 - 在最外面的块或包中声明的变量。

以下示例以简单形式显示了LocalGlobal变量的用法-

<span style="color:#313131">DECLARE 
   <span style="color:#666600">--</span> <span style="color:#7f0055">Global</span> variables  
   num1 number <span style="color:#666600">:=</span> <span style="color:#006666">95</span><span style="color:#666600">;</span>  
   num2 number <span style="color:#666600">:=</span> <span style="color:#006666">85</span><span style="color:#666600">;</span>  
<span style="color:#000088">BEGIN</span>  
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Outer Variable num1: '</span> <span style="color:#666600">||</span> num1<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Outer Variable num2: '</span> <span style="color:#666600">||</span> num2<span style="color:#666600">);</span> 
   DECLARE  
      <span style="color:#666600">--</span> <span style="color:#7f0055">Local</span> variables 
      num1 number <span style="color:#666600">:=</span> <span style="color:#006666">195</span><span style="color:#666600">;</span>  
      num2 number <span style="color:#666600">:=</span> <span style="color:#006666">185</span><span style="color:#666600">;</span>  
   <span style="color:#000088">BEGIN</span>  
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Inner Variable num1: '</span> <span style="color:#666600">||</span> num1<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Inner Variable num2: '</span> <span style="color:#666600">||</span> num2<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span><span style="color:#666600">;</span>  
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

执行上述代码时,会产生以下结果 -

<span style="color:#313131">Outer Variable num1: 95 
Outer Variable num2: 85 
Inner Variable num1: 195 
Inner Variable num2: 185  

PL/SQL procedure successfully completed. 
</span>

将SQL查询结果分配给PL / SQL变量

您可以使用SQL 的SELECT INTO语句为PL / SQL变量赋值。对于SELECT列表中的每个项目,INTO列表中必须有对应的类型兼容变量。以下示例说明了该概念。让我们创建一个名为CUSTOMERS的表 -

对于SQL语句,请参阅SQL教程

<span style="color:#313131">CREATE TABLE CUSTOMERS<span style="color:#666600">(</span> 
   ID   INT NOT NULL<span style="color:#666600">,</span> 
   NAME VARCHAR <span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">)</span> NOT NULL<span style="color:#666600">,</span> 
   AGE INT NOT NULL<span style="color:#666600">,</span> 
   ADDRESS CHAR <span style="color:#666600">(</span><span style="color:#006666">25</span><span style="color:#666600">),</span> 
   SALARY   DECIMAL <span style="color:#666600">(</span><span style="color:#006666">18</span><span style="color:#666600">,</span> <span style="color:#006666">2</span><span style="color:#666600">),</span>        
   PRIMARY KEY <span style="color:#666600">(</span>ID<span style="color:#666600">)</span> 
<span style="color:#666600">);</span>  

<span style="color:#7f0055">Table</span> <span style="color:#7f0055">Created</span>  </span>

现在让我们在表格中插入一些值 -

<span style="color:#313131">INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">,</span> <span style="color:#008800">'Ramesh'</span><span style="color:#666600">,</span> <span style="color:#006666">32</span><span style="color:#666600">,</span> <span style="color:#008800">'Ahmedabad'</span><span style="color:#666600">,</span> <span style="color:#006666">2000.00</span> <span style="color:#666600">);</span>  

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">,</span> <span style="color:#008800">'Khilan'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Delhi'</span><span style="color:#666600">,</span> <span style="color:#006666">1500.00</span> <span style="color:#666600">);</span>  

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">,</span> <span style="color:#008800">'kaushik'</span><span style="color:#666600">,</span> <span style="color:#006666">23</span><span style="color:#666600">,</span> <span style="color:#008800">'Kota'</span><span style="color:#666600">,</span> <span style="color:#006666">2000.00</span> <span style="color:#666600">);</span>
  
INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">4</span><span style="color:#666600">,</span> <span style="color:#008800">'Chaitali'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Mumbai'</span><span style="color:#666600">,</span> <span style="color:#006666">6500.00</span> <span style="color:#666600">);</span> 
 
INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span> <span style="color:#008800">'Hardik'</span><span style="color:#666600">,</span> <span style="color:#006666">27</span><span style="color:#666600">,</span> <span style="color:#008800">'Bhopal'</span><span style="color:#666600">,</span> <span style="color:#006666">8500.00</span> <span style="color:#666600">);</span>  

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">6</span><span style="color:#666600">,</span> <span style="color:#008800">'Komal'</span><span style="color:#666600">,</span> <span style="color:#006666">22</span><span style="color:#666600">,</span> <span style="color:#008800">'MP'</span><span style="color:#666600">,</span> <span style="color:#006666">4500.00</span> <span style="color:#666600">);</span> </span>

以下程序使用SQL的SELECT INTO子句将上表中的值分配给PL / SQL变量-

<span style="color:#313131">DECLARE 
   c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type <span style="color:#666600">:=</span> <span style="color:#006666">1</span><span style="color:#666600">;</span> 
   c_name  customers<span style="color:#666600">.</span>name<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_sal  customers<span style="color:#666600">.</span>salary<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   SELECT name<span style="color:#666600">,</span> address<span style="color:#666600">,</span> salary INTO c_name<span style="color:#666600">,</span> c_addr<span style="color:#666600">,</span> c_sal 
   FROM customers 
   WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span>  
   dbms_output<span style="color:#666600">.</span>put_line 
   <span style="color:#666600">(</span><span style="color:#008800">'Customer '</span> <span style="color:#666600">||</span>c_name <span style="color:#666600">||</span> <span style="color:#008800">' from '</span> <span style="color:#666600">||</span> c_addr <span style="color:#666600">||</span> <span style="color:#008800">' earns '</span> <span style="color:#666600">||</span> c_sal<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

执行上述代码时,会产生以下结果 -

<span style="color:#313131">Customer Ramesh from Ahmedabad earns 2000  

PL/SQL procedure completed successfully
</span>

PL / SQL - 常量和文字

在本章中,我们将讨论PL / SQL中的常量文字。常量保存一个声明的值,在程序中不会更改。常量声明指定其名称,数据类型和值,并为其分配存储。声明也可以强加NOT NULL约束

声明一个常量

使用CONSTANT关键字声明常量。它需要初始值,不允许更改该值。例如 -

<span style="color:#313131">PI CONSTANT NUMBER <span style="color:#666600">:=</span> <span style="color:#006666">3.141592654</span><span style="color:#666600">;</span> 
DECLARE 
   <span style="color:#666600">--</span> constant declaration 
   pi constant number <span style="color:#666600">:=</span> <span style="color:#006666">3.141592654</span><span style="color:#666600">;</span> 
   <span style="color:#666600">--</span> other declarations 
   radius number<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span><span style="color:#006666">2</span><span style="color:#666600">);</span>  
   dia number<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span><span style="color:#006666">2</span><span style="color:#666600">);</span>  
   circumference number<span style="color:#666600">(</span><span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#006666">2</span><span style="color:#666600">);</span> 
   area number <span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">,</span> <span style="color:#006666">2</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span>  
   <span style="color:#666600">--</span> processing 
   radius <span style="color:#666600">:=</span> <span style="color:#006666">9.5</span><span style="color:#666600">;</span>  
   dia <span style="color:#666600">:=</span> radius <span style="color:#666600">*</span> <span style="color:#006666">2</span><span style="color:#666600">;</span>  
   circumference <span style="color:#666600">:=</span> <span style="color:#006666">2.0</span> <span style="color:#666600">*</span> pi <span style="color:#666600">*</span> radius<span style="color:#666600">;</span> 
   area <span style="color:#666600">:=</span> pi <span style="color:#666600">*</span> radius <span style="color:#666600">*</span> radius<span style="color:#666600">;</span> 
   <span style="color:#666600">--</span> output 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Radius: '</span> <span style="color:#666600">||</span> radius<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Diameter: '</span> <span style="color:#666600">||</span> dia<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Circumference: '</span> <span style="color:#666600">||</span> circumference<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Area: '</span> <span style="color:#666600">||</span> area<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Radius: 9.5 
Diameter: 19 
Circumference: 59.69 
Area: 283.53  

Pl/SQL procedure successfully completed. 
</span>

PL / SQL文字

文字是未由标识符表示的显式数字,字符,字符串或布尔值。例如,TRUE,786,NULL,'tutorialspoint'都是Boolean,number或string类型的文字。PL / SQL,文字区分大小写。PL / SQL支持以下类型的文字 -

  • 数字文字
  • 字符文字
  • 字符串文字
  • BOOLEAN文学
  • 日期和时间文字

下表提供了所有这些文字值类别的示例。

S.No 文字类型和示例
1

数字文字

050 78 -14 0 +32767

6.6667 0.0 -12.0 3.14159 +7800.00

6E5 1.0E-8 3.14159e0 -1E38 -9.5e-3

2

字符文字

'A''%''9''''''''''

3

字符串文字

'你好,世界!'

'教程点'

'19 -nov-12'

4

BOOLEAN文学

TRUE,FALSE和NULL。

日期和时间文字

日期'1978-12-25';

TIMESTAMP'2012-10-29 12:01:01';

要在字符串文字中嵌入单引号,请将两个单引号放在一起,如下面的程序所示 -

<span style="color:#313131">DECLARE 
   message  varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">):=</span> <span style="color:#008800">'That''s tutorialspoint.com!'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>message<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">That's tutorialspoint.com!  

PL/SQL procedure successfully completed.
</span>

PL / SQL - 运算符

在本章中,我们将讨论PL / SQL中的运算符。运算符是告诉编译器执行特定数学或逻辑操作的符号。PL / SQL语言内置运算符丰富,并提供以下类型的运算符 -

  • 算术运算符
  • 关系运算符
  • 比较运算符
  • 逻辑运算符
  • 字符串运算符

在这里,我们将逐一理解算术,关系,比较和逻辑运算符。字符串运算符将在后面的章节中讨论 - PL / SQL - 字符串

算术运算符

下表显示了PL / SQL支持的所有算术运算符。让我们假设变量A保持10,变量B保持5,然后 -

显示示例

操作者 描述
+ 添加两个操作数 A + B将给出15
- 从第一个减去第二个操作数 A - B将给5
* 将两个操作数相乘 A * B将给出50
/ 用除分子除分子 A / B将给2
** 指数运算符,将一个操作数提升到其他的幂 A ** B将给出100000

关系运算符

关系运算符比较两个表达式或值并返回布尔结果。下表显示了PL / SQL支持的所有关系运算符。让我们假设变量A保持10,变量B保持20,然后 -

显示示例

操作者 描述
= 检查两个操作数的值是否相等,如果是,则条件变为真。 (A = B)不是真的。

!=

<>

〜=

检查两个操作数的值是否相等,如果值不相等则条件变为真。 (A!= B)是真的。
> 检查左操作数的值是否大于右操作数的值,如果是,则条件变为真。 (A> B)不是真的。
< 检查左操作数的值是否小于右操作数的值,如果是,则条件变为真。 (A <B)是真的。
> = 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件变为真。 (A> = B)不是真的。
<= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件变为真。 (A <= B)是真的

比较运算符

比较运算符用于比较一个表达式与另一个表达式。结果始终为TRUE,FALSENULL

显示示例

操作者 描述
喜欢 LIKE运算符将字符,字符串或CLOB值与模式进行比较,如果值与模式匹配则返回TRUE,否则返回FALSE。 如果'Zara Ali'喜欢'Z%A_i'返回布尔值true,而'Nuha Ali'喜欢'Z%A_i'返回布尔值false。
之间 BETWEEN运算符测试值是否在指定范围内。x BETWEEN a AND b表示x> = a且x <= b。 如果x = 10那么,5到20之间的x返回true,5到10之间的x返回true,但是11到20之间的x返回false。
IN运算符测试设置成员资格。x IN(set)表示x等于set的任何成员。 如果x ='m'那么,x in('a','b','c')返回布尔值false但x in('m','n','o')返回布尔值true。
一片空白 如果操作数为NULL,则IS NULL运算符返回BOOLEAN值TRUE,如果不为NULL,则返回FALSE。涉及NULL值的比较总是产生NULL。 如果x ='m',则'x为null'返回布尔值false。

逻辑运算符

下表显示了PL / SQL支持的逻辑运算符。所有这些运算符都处理布尔操作数并生成布尔结果。让我们假设变量A成立,变量B成立假,然后 -

显示示例

操作者 描述 例子
称为逻辑AND运算符。如果两个操作数均为真,则条件成立。 (A和B)是假的。
要么 称为逻辑OR运算符。如果两个操作数中的任何一个为真,则条件成立。 (A或B)是真的。
称为逻辑NOT运算符。用于反转其操作数的逻辑状态。如果条件为真,则Logical NOT运算符将使其为假。 不(A和B)是真的。

PL / SQL运算符优先级

运算符优先级确定表达式中的术语分组。这会影响表达式的计算方式。某些运营商的优先级高于其他运营商; 例如,乘法运算符的优先级高于加法运算符。

例如,x = 7 + 3 * 2 ; 这里,x被赋值为13,而不是20,因为operator *的优先级高于+,所以它首先乘以3 * 2然后加到7中

此处,具有最高优先级的运算符显示在表的顶部,具有最低优先级的运算符显示在底部。在表达式中,将首先评估更高优先级的运算符。

运算符的优先级如下:=,<,>,<=,> =,<>,!=,〜=,^ =,IS NULL,LIKE,BETWEEN,IN。

显示示例

操作者 手术
**
+, - 身份,否定
*,/ 乘法,除法
+, - ,|| 加法,减法,连接
对照  
逻辑否定
连词
要么 包容

PL / SQL - 条件

在本章中,我们将讨论PL / SQL中的条件。决策结构要求程序员指定一个或多个要由程序评估或测试的条件,以及在条件被确定为真时要执行的一个或多个语句,以及可选的其他语句,如果条件被确定为假。

以下是大多数编程语言中发现的典型条件(即决策)结构的一般形式 -

PL / SQL中的决策语句

PL / SQL编程语言提供以下类型的决策制定语句。单击以下链接以检查其详细信息。

S.No 声明和说明
1 IF - 那么声明

IF语句与使用关键字封闭的语句序列相关联的条件THENEND IF。如果条件为真,则执行语句,如果条件为false或NULL,则IF语句不执行任何操作。

2 IF-THEN-ELSE声明

IF语句添加关键字ELSE,后跟另一个语句序列。如果条件为false或NULL,则只执行替代语句序列。它确保执行任一语句序列。

3 IF-THEN-ELSIF声明

它允许您在几种选择之间进行选择。

4 案例陈述

与IF语句一样,CASE语句选择要执行的一个语句序列。

但是,要选择序列,CASE语句使用选择器而不是多个布尔表达式。选择器是一个表达式,其值用于选择多个备选项之一。

搜索CASE声明

搜索到的CASE语句没有选择器,它的WHEN子句包含产生布尔值的搜索条件。

6 嵌套的IF-THEN-ELSE

您可以在另一个IF-THENIF-THEN-ELSIF语句中使用一个IF-THENIF-THEN-ELSIF语句。

PL / SQL - 循环

在本章中,我们将讨论PL / SQL中的循环。可能存在需要多次执行代码块的情况。通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。

编程语言提供各种控制结构,允许更复杂的执行路径。

循环语句允许我们多次执行语句或语句组,以下是大多数编程语言中循环语句的一般形式 -

循环架构

PL / SQL提供以下类型的循环来处理循环要求。单击以下链接以检查其详细信息。

S.No 循环类型和描述
1 PL / SQL基本循环

在此循环结构中,语句序列包含在LOOP和END LOOP语句之间。在每次迭代时,执行语句序列,然后控制在循环的顶部重新开始。

2 PL / SQL WHILE循环

在给定条件为真时重复语句或语句组。它在执行循环体之前测试条件。

3 PL / SQL FOR LOOP

多次执行一系列语句,并缩写管理循环变量的代码。

4 PL / SQL中的嵌套循环

您可以在任何其他基本循环中使用一个或多个循环,或者用于循环。

标记PL / SQL循环

可以标记PL / SQL循环。标签应该用双尖括号(<<和>>)括起来,并出现在LOOP语句的开头。标签名称也可以出现在LOOP语句的末尾。您可以使用EXIT语句中的标签退出循环。

以下计划说明了这一概念 -

<span style="color:#313131">DECLARE 
   i number<span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
   j number<span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600"><<</span> outer_loop <span style="color:#666600">>></span> 
   FOR i IN <span style="color:#006666">1.</span><span style="color:#666600">.</span><span style="color:#006666">3</span> LOOP 
      <span style="color:#666600"><<</span> inner_loop <span style="color:#666600">>></span> 
      FOR j IN <span style="color:#006666">1.</span><span style="color:#666600">.</span><span style="color:#006666">3</span> LOOP 
         dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'i is: '</span><span style="color:#666600">||</span> i <span style="color:#666600">||</span> <span style="color:#008800">' and j is: '</span> <span style="color:#666600">||</span> j<span style="color:#666600">);</span> 
      <span style="color:#000088">END</span> loop inner_loop<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> loop outer_loop<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">i is: 1 and j is: 1 
i is: 1 and j is: 2 
i is: 1 and j is: 3 
i is: 2 and j is: 1 
i is: 2 and j is: 2 
i is: 2 and j is: 3 
i is: 3 and j is: 1 
i is: 3 and j is: 2 
i is: 3 and j is: 3  

PL/SQL procedure successfully completed. 
</span>

循环控制语句

循环控制语句将执行从其正常序列更改。当执行离开作用域时,将销毁在该作用域中创建的所有自动对象。

PL / SQL支持以下控制语句。标记循环也有助于将控件置于循环之外。单击以下链接以查看其详细信息。

S.No 控制声明和描述
1 退出声明

Exit语句完成循环并且控制在END LOOP之后立即传递给语句。

2 CONTINUE声明

导致循环跳过其身体的其余部分,并在重复之前立即重新测试其状态。

3 GOTO声明

将控制转移到带标签的声明。虽然不建议在程序中使用GOTO语句。

PL / SQL - 字符串

PL / SQL中的字符串实际上是一个具有可选大小规范的字符序列。字符可以是数字,字母,空白,特殊字符或所有字符的组合。PL / SQL提供三种字符串 -

  • 固定长度的字符串 - 在这样的字符串中,程序员在声明字符串时指定长度。字符串右边用空格填充到指定的长度。

  • 可变长度字符串 - 在此类字符串中,指定字符串的最大长度最大为32,767,并且不会发生填充。

  • 字符大对象(CLOB) - 这些是可变长度的字符串,最多可达128 TB。

PL / SQL字符串可以是变量或文字。字符串文字用引号括起来。例如,

<span style="color:#313131">'This is a string literal.' Or 'hello world'
</span>

要在字符串文字中包含单引号,您需要在彼此旁边键入两个单引号。例如,

<span style="color:#313131">'this isn''t what it looks like'
</span>

声明字符串变量

Oracle数据库提供了许多字符串数据类型,例如CHAR,NCHAR,VARCHAR2,NVARCHAR2,CLOB和NCLOB。前缀为“N” 数据类型是“国家字符集”数据类型,用于存储Unicode字符数据。

如果需要声明可变长度字符串,则必须提供该字符串的最大长度。例如,VARCHAR2数据类型。以下示例说明了声明和使用一些字符串变量 -

<span style="color:#313131">DECLARE 
   name varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">);</span> 
   company varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">);</span> 
   introduction clob<span style="color:#666600">;</span> 
   choice <span style="color:#000088">char</span><span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   name <span style="color:#666600">:=</span> <span style="color:#008800">'John Smith'</span><span style="color:#666600">;</span> 
   company <span style="color:#666600">:=</span> <span style="color:#008800">'Infotech'</span><span style="color:#666600">;</span> 
   introduction <span style="color:#666600">:=</span> <span style="color:#008800">' Hello! I''m John Smith from Infotech.'</span><span style="color:#666600">;</span> 
   choice <span style="color:#666600">:=</span> <span style="color:#008800">'y'</span><span style="color:#666600">;</span> 
   IF choice <span style="color:#666600">=</span> <span style="color:#008800">'y'</span> THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>name<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>company<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>introduction<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">John Smith 
Infotech Corporation 
Hello! I'm John Smith from Infotech.  

PL/SQL procedure successfully completed
</span>

要声明固定长度的字符串,请使用CHAR数据类型。在这里,您不必为固定长度变量指定最大长度。如果不使用长度约束,Oracle数据库将自动使用所需的最大长度。以下两个声明是相同的 -

<span style="color:#313131">red_flag CHAR(1) := 'Y'; 
 red_flag CHAR   := 'Y';
</span>

PL / SQL字符串函数和操作符

PL / SQL提供连接运算符(||)来连接两个字符串。下表提供了PL / SQL提供的字符串函数 -

S.No 功能与目的
1

ASCII(X);

返回字符x的ASCII值。

2

CHR(X);

返回ASCII值为x的字符。

3

CONCAT(x,y);

连接字符串x和y并返回附加的字符串。

4

INITCAP(X);

将x中每个单词的首字母转换为大写并返回该字符串。

INSTR(x,find_string [,start] [,occurrence]);

在x中搜索find_string并返回它出现的位置。

6

INSTRB(X);

返回另一个字符串中字符串的位置,但返回以字节为单位的值。

7

长度(X);

返回x中的字符数。

8

LENGTHB(X);

返回单字节字符集的字符串长度(以字节为单位)。

9

LOWER(X);

将x中的字母转换为小写并返回该字符串。

10

LPAD(x,width [,pad_string]);

填充x左侧有空格,以使字符串的总长度达到宽度字符。

11

LTRIM(x [,trim_string]);

修剪x左侧的字符。

12

NANVL(x,值);

如果x与NaN特殊值(不是数字)匹配,则返回值,否则返回x

13

NLS_INITCAP(X);

与INITCAP函数相同,但它可以使用NLSSORT指定的其他排序方法。

14

NLS_LOWER(x);

与LOWER函数相同,只是它可以使用NLSSORT指定的其他排序方法。

15

NLS_UPPER(X);

与UPPER函数相同,但它可以使用NLSSORT指定的其他排序方法。

16

NLSSORT(X);

更改排序字符的方法。必须在任何NLS功能之前指定; 否则,将使用默认排序。

17

NVL(x,值);

如果x为null,则返回值; 否则,返回x。

18

NVL2(x,value1,value2);

如果x不为null,则返回value1; 如果x为null,则返回value2。

19

REPLACE(x,search_string,replace_string);

x中搜索search_string并将其替换为replace_string。

20

RPAD(x,width [,pad_string]);

x到右边。

21

RTRIM(x [,trim_string]);

从右边修剪x

22

SOUNDEX(x);

返回包含x的语音表示的字符串。

23

SUBSTR(x,start [,length]);

返回x的子字符串,该子字符串从start指定的位置开始。可以提供子串的可选长度。

24

SUBSTRB(X);

与SUBSTR相同,除了参数以字节表示而不是单字节字符系统的字符。

25

TRIM([trim_char FROM)x);

修剪x左右两侧的字符。

26

UPPER(X);

将x中的字母转换为大写并返回该字符串。

现在让我们通过几个例子来理解这个概念 -

例1

<span style="color:#313131">DECLARE 
   greetings varchar2<span style="color:#666600">(</span><span style="color:#006666">11</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#008800">'hello world'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>UPPER<span style="color:#666600">(</span>greetings<span style="color:#666600">));</span> 
    
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>LOWER<span style="color:#666600">(</span>greetings<span style="color:#666600">));</span> 
    
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>INITCAP<span style="color:#666600">(</span>greetings<span style="color:#666600">));</span> 
    
   <span style="color:#880000">/* retrieve the first character in the string */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> SUBSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#006666">1</span><span style="color:#666600">,</span> <span style="color:#006666">1</span><span style="color:#666600">));</span> 
    
   <span style="color:#880000">/* retrieve the last character in the string */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> SUBSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#666600">-</span><span style="color:#006666">1</span><span style="color:#666600">,</span> <span style="color:#006666">1</span><span style="color:#666600">));</span> 
    
   <span style="color:#880000">/* retrieve five characters,  
      starting from the seventh position. */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> SUBSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#006666">5</span><span style="color:#666600">));</span> 
    
   <span style="color:#880000">/* retrieve the remainder of the string, 
      starting from the second position. */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> SUBSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#006666">2</span><span style="color:#666600">));</span> 
     
   <span style="color:#880000">/* find the location of the first "e" */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> INSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#008800">'e'</span><span style="color:#666600">));</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">HELLO WORLD 
hello world 
Hello World 
h 
d 
World 
ello World 
2  

PL/SQL procedure successfully completed.
</span>

例2

<span style="color:#313131">DECLARE 
   greetings varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#008800">'......Hello World.....'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>RTRIM<span style="color:#666600">(</span>greetings<span style="color:#666600">,</span><span style="color:#008800">'.'</span><span style="color:#666600">));</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>LTRIM<span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#008800">'.'</span><span style="color:#666600">));</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>TRIM<span style="color:#666600">(</span> <span style="color:#008800">'.'</span> <span style="color:#000088">from</span> greetings<span style="color:#666600">));</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">......Hello World  
Hello World..... 
Hello World  

PL/SQL procedure successfully completed. 
</span>

PL / SQL - 数组

在本章中,我们将讨论PL / SQL中的数组。PL / SQL编程语言提供了一个名为VARRAY的数据结构,它可以存储相同类型元素的固定大小顺序集合。varray用于存储有序的数据集合,但通常最好将数组视为相同类型的变量集合。

所有varrays都包含连续的内存位置。最低地址对应于第一个元素,最高地址对应于最后一个元素。

PL / SQL中的变量

数组是集合类型数据的一部分,它代表可变大小的数组。我们将在后面的“PL / SQL集合”一章中研究其他集合类型。

varray中的每个元素都有一个与之关联的索引。它还具有可以动态更改的最大大小。

创建Varray类型

使用CREATE TYPE语句创建varray类型。您必须指定存储在varray中的最大大小和元素类型。

在架构级别创建VARRAY类型的基本语法是 -

<span style="color:#313131">CREATE OR REPLACE TYPE varray_type_name IS VARRAY(n) of <element_type>
</span>

哪里,

  • varray_type_name是一个有效的属性名称,
  • n是varray中元素的数量(最大值),
  • element_type是数组元素的数据类型。

可以使用ALTER TYPE语句更改varray的最大大小。

例如,

<span style="color:#313131">CREATE <span style="color:#7f0055">Or</span> REPLACE TYPE namearray AS VARRAY<span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">)</span> OF VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">);</span> 
<span style="color:#666600">/</span> 

<span style="color:#7f0055">Type</span> created<span style="color:#666600">.</span></span>

在PL / SQL块中创建VARRAY类型的基本语法是 -

 

<span style="color:#313131">TYPE varray_type_name IS VARRAY(n) of <element_type>
</span>

例如 -

<span style="color:#313131">TYPE namearray IS VARRAY<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">)</span> OF VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">);</span> 
<span style="color:#7f0055">Type</span> grades IS VARRAY<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">)</span> OF INTEGER<span style="color:#666600">;</span></span>

现在让我们通过几个例子来理解这个概念 -

例1

以下程序说明了varrays的使用 -

<span style="color:#313131">DECLARE 
   type namesarray IS VARRAY<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">)</span> OF VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">);</span> 
   type grades IS VARRAY<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">)</span> OF INTEGER<span style="color:#666600">;</span> 
   names namesarray<span style="color:#666600">;</span> 
   marks grades<span style="color:#666600">;</span> 
   total integer<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   names <span style="color:#666600">:=</span> namesarray<span style="color:#666600">(</span><span style="color:#008800">'Kavita'</span><span style="color:#666600">,</span> <span style="color:#008800">'Pritam'</span><span style="color:#666600">,</span> <span style="color:#008800">'Ayan'</span><span style="color:#666600">,</span> <span style="color:#008800">'Rishav'</span><span style="color:#666600">,</span> <span style="color:#008800">'Aziz'</span><span style="color:#666600">);</span> 
   marks<span style="color:#666600">:=</span> grades<span style="color:#666600">(</span><span style="color:#006666">98</span><span style="color:#666600">,</span> <span style="color:#006666">97</span><span style="color:#666600">,</span> <span style="color:#006666">78</span><span style="color:#666600">,</span> <span style="color:#006666">87</span><span style="color:#666600">,</span> <span style="color:#006666">92</span><span style="color:#666600">);</span> 
   total <span style="color:#666600">:=</span> names<span style="color:#666600">.</span>count<span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Total '</span><span style="color:#666600">||</span> total <span style="color:#666600">||</span> <span style="color:#008800">' Students'</span><span style="color:#666600">);</span> 
   FOR i <span style="color:#000088">in</span> <span style="color:#006666">1</span> <span style="color:#666600">..</span> total LOOP 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Student: '</span> <span style="color:#666600">||</span> names<span style="color:#666600">(</span>i<span style="color:#666600">)</span> <span style="color:#666600">||</span> <span style="color:#008800">' 
      Marks: '</span> <span style="color:#666600">||</span> marks<span style="color:#666600">(</span>i<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Total 5 Students 
Student: Kavita  Marks: 98 
Student: Pritam  Marks: 97 
Student: Ayan  Marks: 78 
Student: Rishav  Marks: 87 
Student: Aziz  Marks: 92 

PL/SQL procedure successfully completed. 
</span>

请注意 -

  • 在Oracle环境中,varrays的起始索引始终为1。

  • 您可以使用varray类型的构造方法初始化varray元素,该方法与varray具有相同的名称。

  • Varrays是一维数组。

  • varray在声明时自动为NULL,必须在引用其元素之前进行初始化。

例2

varray的元素也可以是任何数据库表的%ROWTYPE或任何数据库表字段的%TYPE。以下示例说明了该概念。

我们将使用存储在我们数据库中的CUSTOMERS表作为 -

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+ 
</span>

下面的示例使用了光标,您将在另一章中详细研究。

<span style="color:#313131">DECLARE 
   CURSOR c_customers <span style="color:#000088">is</span> 
   SELECT  name FROM customers<span style="color:#666600">;</span> 
   type c_list <span style="color:#000088">is</span> varray <span style="color:#666600">(</span><span style="color:#006666">6</span><span style="color:#666600">)</span> of customers<span style="color:#666600">.</span>name<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   name_list c_list <span style="color:#666600">:=</span> c_list<span style="color:#666600">();</span> 
   counter integer <span style="color:#666600">:=</span><span style="color:#006666">0</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   FOR n IN c_customers LOOP 
      counter <span style="color:#666600">:=</span> counter <span style="color:#666600">+</span> <span style="color:#006666">1</span><span style="color:#666600">;</span> 
      name_list<span style="color:#666600">.</span>extend<span style="color:#666600">;</span> 
      name_list<span style="color:#666600">(</span>counter<span style="color:#666600">)</span>  <span style="color:#666600">:=</span> n<span style="color:#666600">.</span>name<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer('</span><span style="color:#666600">||</span>counter <span style="color:#666600">||</span><span style="color:#008800">'):'</span><span style="color:#666600">||</span>name_list<span style="color:#666600">(</span>counter<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131"><span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">):</span> <span style="color:#7f0055">Ramesh</span>  
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">):</span> <span style="color:#7f0055">Khilan</span>  
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">):</span> kaushik     
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">4</span><span style="color:#666600">):</span> <span style="color:#7f0055">Chaitali</span>  
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">):</span> <span style="color:#7f0055">Hardik</span>  
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">6</span><span style="color:#666600">):</span> <span style="color:#7f0055">Komal</span>  

PL<span style="color:#666600">/</span>SQL procedure successfully completed<span style="color:#666600">.</span> </span>

PL / SQL - 程序

在本章中,我们将讨论PL / SQL中的过程。甲子程序是程序单元/模块,其执行特定的任务。这些子程序组合在一起形成更大的程序。这基本上被称为“模块化设计”。子程序可以由另一个子程序或程序调用,称为调用程序

可以创建子程序 -

  • 在架构级别
  • 在包内
  • 在PL / SQL块中

在模式级别,子程序是一个独立的子程序。它是使用CREATE PROCEDURE或CREATE FUNCTION语句创建的。它存储在数据库中,可以使用DROP PROCEDURE或DROP FUNCTION语句删除。

在包内创建的子程序是打包的子程序。它存储在数据库中,只有在使用DROP PACKAGE语句删除包时才能删除它。我们将在“PL / SQL - 包”一章中讨论包。

PL / SQL子程序被命名为PL / SQL块,可以使用一组参数调用它们。PL / SQL提供两种子程序 -

  • 函数 - 这些子程序返回单个值; 主要用于计算和返回一个值。

  • 程序 - 这些子程序不直接返回值; 主要用于执行动作。

本章将介绍PL / SQL过程的重要方面。我们将在下一章讨论PL / SQL函数

PL / SQL子程序的一部分

每个PL / SQL子程序都有一个名称,也可能有一个参数列表。与匿名PL / SQL块一样,命名块也将包含以下三个部分 -

S.No 零件和描述
1

声明部分

这是一个可选部分。但是,子程序的声明部分不是以DECLARE关键字开头的。它包含类型,游标,常量,变量,异常和嵌套子程序的声明。这些项目是子程序的本地项目,并在子程序完成执行时不再存在。

2

可执行部分

这是必需部分,包含执行指定操作的语句。

3

异常处理

这也是一个可选部分。它包含处理运行时错误的代码。

创建程序

使用CREATE OR REPLACE PROCEDURE语句创建过程。CREATE OR REPLACE PROCEDURE语句的简化语法如下 -

<span style="color:#313131">CREATE <span style="color:#666600">[</span>OR REPLACE<span style="color:#666600">]</span> PROCEDURE procedure_name 
<span style="color:#666600">[(</span>parameter_name <span style="color:#666600">[</span>IN <span style="color:#666600">|</span> OUT <span style="color:#666600">|</span> IN OUT<span style="color:#666600">]</span> type <span style="color:#666600">[,</span> <span style="color:#666600">...])]</span> 
<span style="color:#666600">{</span>IS <span style="color:#666600">|</span> AS<span style="color:#666600">}</span> 
<span style="color:#000088">BEGIN</span> 
  <span style="color:#666600"><</span> procedure_body <span style="color:#666600">></span> 
<span style="color:#000088">END</span> procedure_name<span style="color:#666600">;</span> </span>

哪里,

  • procedure-name指定过程的名称

  • [OR REPLACE]选项允许修改现有过程。

  • 可选参数列表包含参数的名称,模式和类型。IN表示将从外部传递的值,OUT表示将用于在过程外返回值的参数。

  • procedure-body包含可执行部分。

  • 使用AS关键字代替IS关键字来创建独立过程。

以下示例创建一个显示字符串'Hello World!'的简单过程。在执行时在屏幕上。

<span style="color:#313131">CREATE OR REPLACE PROCEDURE greetings 
AS 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Hello World!'</span><span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当使用SQL提示执行上述代码时,它将产生以下结果 -

<span style="color:#313131">Procedure created.
</span>

执行独立过程

可以通过两种方式调用独立过程 -

  • 使用EXECUTE关键字

  • 从PL / SQL块调用过程的名称

可以使用EXECUTE关键字调用上述名为'greetings'的过程-

<span style="color:#313131">EXECUTE greetings;
</span>

以上电话会显示 -

<span style="color:#313131">Hello World

PL/SQL procedure successfully completed.
</span>

也可以从另一个PL / SQL块调用该过程 -

<span style="color:#313131"><span style="color:#000088">BEGIN</span> 
   greetings<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

以上电话会显示 -

<span style="color:#313131">Hello World  

PL/SQL procedure successfully completed. 
</span>

删除独立过程

使用DROP PROCEDURE语句删除独立过程。删除程序的语法是 -

<span style="color:#313131">DROP PROCEDURE procedure-name; 
</span>

您可以使用以下声明删除问候程序 -

<span style="color:#313131">DROP PROCEDURE greetings; 
</span>

PL / SQL子程序中的参数模式

下表列出了PL / SQL子程序中的参数模式 -

S.No 参数模式和说明
1

IN参数允许您将值传递给子程序。它是一个只读参数。在子程序内部,IN参数的作用类似于常量。它无法分配值。您可以将常量,文字,初始化变量或表达式作为IN参数传递。您也可以将其初始化为默认值; 但是,在这种情况下,子程序调用中省略了它。它是参数传递的默认模式。参数通过引用传递

2

OUT

OUT参数向调用程序返回一个值。在子程序内部,OUT参数就像一个变量。您可以在分配值后更改其值并引用该值。实际参数必须是可变的,并按值传递

3

进出

一个IN OUT参数传递的初始值到一个子程序,并返回更新值给调用者。可以为其分配值,并且可以读取该值。

对应于IN OUT形式参数的实际参数必须是变量,而不是常量或表达式。必须为正式参数分配值。实际参数按值传递。

IN&OUT模式示例1

该程序找到最少两个值。这里,该过程使用IN模式获取两个数字,并使用OUT参数返回其最小值。

<span style="color:#313131">DECLARE 
   a number<span style="color:#666600">;</span> 
   b number<span style="color:#666600">;</span> 
   c number<span style="color:#666600">;</span>
PROCEDURE findMin<span style="color:#666600">(</span>x IN number<span style="color:#666600">,</span> y IN number<span style="color:#666600">,</span> z OUT number<span style="color:#666600">)</span> IS 
<span style="color:#000088">BEGIN</span> 
   IF x <span style="color:#666600"><</span> y THEN 
      z<span style="color:#666600">:=</span> x<span style="color:#666600">;</span> 
   ELSE 
      z<span style="color:#666600">:=</span> y<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span>   
<span style="color:#000088">BEGIN</span> 
   a<span style="color:#666600">:=</span> <span style="color:#006666">23</span><span style="color:#666600">;</span> 
   b<span style="color:#666600">:=</span> <span style="color:#006666">45</span><span style="color:#666600">;</span> 
   findMin<span style="color:#666600">(</span>a<span style="color:#666600">,</span> b<span style="color:#666600">,</span> c<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">' Minimum of (23, 45) : '</span> <span style="color:#666600">||</span> c<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Minimum of (23, 45) : 23  

PL/SQL procedure successfully completed. 
</span>

IN&OUT模式示例2

此过程计算传递值的平方值。此示例显示了我们如何使用相同的参数接受值,然后返回另一个结果。

<span style="color:#313131">DECLARE 
   a number<span style="color:#666600">;</span> 
PROCEDURE squareNum<span style="color:#666600">(</span>x IN OUT number<span style="color:#666600">)</span> IS 
<span style="color:#000088">BEGIN</span> 
  x <span style="color:#666600">:=</span> x <span style="color:#666600">*</span> x<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span>  
<span style="color:#000088">BEGIN</span> 
   a<span style="color:#666600">:=</span> <span style="color:#006666">23</span><span style="color:#666600">;</span> 
   squareNum<span style="color:#666600">(</span>a<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">' Square of (23): '</span> <span style="color:#666600">||</span> a<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Square of (23): 529 

PL/SQL procedure successfully completed.
</span>

传递参数的方法

实际参数可以通过三种方式传递 -

  • 位置符号
  • 命名符号
  • 混合符号

位置符号

在位置表示法中,您可以将程序称为 -

<span style="color:#313131">findMin(a, b, c, d);
</span>

在位置表示法中,第一个实际参数代替第一个形式参数; 第二个实际参数代替第二个形式参数,依此类推。因此,a代替x,b代替y,c代替zd代替m

命名表示法

在命名表示法中,实际参数使用箭头符号(=>)与形式参数相关联。程序调用将如下所示 -

<span style="color:#313131">findMin(x => a, y => b, z => c, m => d);
</span>

混合符号

在混合符号中,您可以在过程调用中混合使用两种符号; 但是,位置表示法应该在命名表示法之前。

以下电话是合法的 -

<span style="color:#313131">findMin(a, b, c, m => d);
</span>

但是,这不合法:

<span style="color:#313131">findMin(x => a, b, c, d); 
</span>

PL / SQL - 功能

在本章中,我们将讨论PL / SQL中的函数。函数与过程相同,只是它返回一个值。因此,前一章的所有讨论也适用于函数。

创建一个函数

使用CREATE FUNCTION语句创建独立函数。CREATE OR REPLACE PROCEDURE语句的简化语法如下 -

<span style="color:#313131">CREATE [OR REPLACE] FUNCTION function_name 
[(parameter_name [IN | OUT | IN OUT] type [, ...])] 
RETURN return_datatype 
{IS | AS} 
BEGIN 
   < function_body > 
END [function_name];
</span>

哪里,

  • function-name指定函数的名称

  • [OR REPLACE]选项允许修改现有功能。

  • 可选参数列表包含参数的名称,模式和类型。IN表示将从外部传递的值,OUT表示将用于在过程外返回值的参数。

  • 该函数必须包含return语句。

  • RETURN子句指定的数据类型,你打算从函数返回。

  • function-body包含可执行部分。

  • 使用AS关键字代替IS关键字来创建独立功能。

以下示例说明了如何创建和调用独立函数。此函数返回customers表中的CUSTOMERS总数。

我们将使用我们在PL / SQL变量章节中创建的CUSTOMERS表-

<span style="color:#313131">Select * from customers; 
 
+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+  
</span>
<span style="color:#313131">CREATE OR REPLACE FUNCTION totalCustomers 
RETURN number IS 
   total number<span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">0</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   SELECT count<span style="color:#666600">(*)</span> <span style="color:#000088">into</span> total 
   FROM customers<span style="color:#666600">;</span> 
    
   RETURN total<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当使用SQL提示执行上述代码时,它将产生以下结果 -

<span style="color:#313131">Function created.
</span>

调用函数

在创建函数时,您可以定义函数必须执行的操作。要使用函数,您必须调用该函数来执行定义的任务。程序调用函数时,程序控制转移到被调用函数。

被调用的函数执行定义的任务,当执行其return语句或到达最后一个结束语句时,它将程序控制返回给主程序。

要调用函数,只需要传递必需的参数和函数名称,如果函数返回值,则可以存储返回的值。以下程序从匿名块调用函数totalCustomers -

<span style="color:#313131">DECLARE 
   c number<span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   c <span style="color:#666600">:=</span> totalCustomers<span style="color:#666600">();</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Total no. of Customers: '</span> <span style="color:#666600">||</span> c<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Total no. of Customers: 6  

PL/SQL procedure successfully completed. 
</span>

以下示例演示了声明,定义和调用简单PL / SQL函数,该函数计算并返回最多两个值。

<span style="color:#313131">DECLARE 
   a number<span style="color:#666600">;</span> 
   b number<span style="color:#666600">;</span> 
   c number<span style="color:#666600">;</span> 
FUNCTION findMax<span style="color:#666600">(</span>x IN number<span style="color:#666600">,</span> y IN number<span style="color:#666600">)</span>  
RETURN number 
IS 
    z number<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   IF x <span style="color:#666600">></span> y THEN 
      z<span style="color:#666600">:=</span> x<span style="color:#666600">;</span> 
   ELSE 
      Z<span style="color:#666600">:=</span> y<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span>  
   RETURN z<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   a<span style="color:#666600">:=</span> <span style="color:#006666">23</span><span style="color:#666600">;</span> 
   b<span style="color:#666600">:=</span> <span style="color:#006666">45</span><span style="color:#666600">;</span>  
   c <span style="color:#666600">:=</span> findMax<span style="color:#666600">(</span>a<span style="color:#666600">,</span> b<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">' Maximum of (23,45): '</span> <span style="color:#666600">||</span> c<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Maximum of (23,45): 45   

PL/SQL procedure successfully completed. 
</span>

PL / SQL递归函数

我们已经看到程序或子程序可能会调用另一个子程序。当子程序调用自身时,它被称为递归调用,该过程称为递归

为了说明这个概念,让我们计算一个数的阶乘。数字n的因子定义为 -

<span style="color:#313131">n! = n*(n-1)! 
   = n*(n-1)*(n-2)! 
      ... 
   = n*(n-1)*(n-2)*(n-3)... 1 
</span>

以下程序通过递归调用自身计算给定数字的阶乘 -

<span style="color:#313131">DECLARE 
   num number<span style="color:#666600">;</span> 
   factorial number<span style="color:#666600">;</span>  
   
FUNCTION fact<span style="color:#666600">(</span>x number<span style="color:#666600">)</span> 
RETURN number  
IS 
   f number<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   IF x<span style="color:#666600">=</span><span style="color:#006666">0</span> THEN 
      f <span style="color:#666600">:=</span> <span style="color:#006666">1</span><span style="color:#666600">;</span> 
   ELSE 
      f <span style="color:#666600">:=</span> x <span style="color:#666600">*</span> fact<span style="color:#666600">(</span>x<span style="color:#666600">-</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
RETURN f<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span>  

<span style="color:#000088">BEGIN</span> 
   num<span style="color:#666600">:=</span> <span style="color:#006666">6</span><span style="color:#666600">;</span> 
   factorial <span style="color:#666600">:=</span> fact<span style="color:#666600">(</span>num<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">' Factorial '</span><span style="color:#666600">||</span> num <span style="color:#666600">||</span> <span style="color:#008800">' is '</span> <span style="color:#666600">||</span> factorial<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Factorial 6 is 720 
  
PL/SQL procedure successfully completed.
</span>

PL / SQL - 游标

在本章中,我们将讨论PL / SQL中的游标。Oracle创建了一个内存区域,称为上下文区域,用于处理SQL语句,该语句包含处理语句所需的所有信息; 例如,处理的行数等

光标是一个指向这个上下文区域。PL / SQL通过游标控制上下文区域。游标保存SQL语句返回的行(一个或多个)。光标所持有的行集称为活动集

您可以命名游标,以便可以在程序中引用它以一次一个地获取和处理SQL语句返回的行。游标有两种类型 -

  • 隐含游标
  • 显式游标

隐含游标

每当执行SQL语句时,当语句没有显式游标时,Oracle会自动创建隐式游标。程序员无法控制隐式游标及其中的信息。

每当发出DML语句(INSERT,UPDATE和DELETE)时,隐式游标都与此语句相关联。对于INSERT操作,游标保存需要插入的数据。对于UPDATE和DELETE操作,游标标识将受影响的行。

在PL / SQL中,您可以将最新的隐式游标称为SQL游标,它始终具有%FOUND,%ISOPEN,%NOTFOUND%ROWCOUNT等属性。SQL游标具有其他属性,%BULK_ROWCOUNT%BULK_EXCEPTIONS,旨在与FORALL语句一起使用。下表提供了最常用属性的说明 -

S.No 属性和描述
1

%FOUND

如果INSERT,UPDATE或DELETE语句影响一行或多行或SELECT INTO语句返回一行或多行,则返回TRUE。否则,它返回FALSE。

2

%未找到

与%FOUND完全相反。如果INSERT,UPDATE或DELETE语句不影响任何行,或者SELECT INTO语句未返回任何行,则返回TRUE。否则,它返回FALSE。

3

%开了

对于隐式游标,始终返回FALSE,因为Oracle在执行其关联的SQL语句后会自动关闭SQL游标。

4

%ROWCOUNT

返回受INSERT,UPDATE或DELETE语句影响的行数,或SELECT INTO语句返回的行数。

任何SQL游标属性都将作为sql%attribute_name访问,如下例所示。

我们将使用我们在前面章节中创建和使用的CUSTOMERS表。

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+
</span>

以下程序将更新表并将每个客户的工资增加500,并使用SQL%ROWCOUNT属性确定受影响的行数 -

<span style="color:#313131">DECLARE  
   total_rows number<span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   UPDATE customers 
   SET salary <span style="color:#666600">=</span> salary <span style="color:#666600">+</span> <span style="color:#006666">500</span><span style="color:#666600">;</span> 
   IF sql<span style="color:#666600">%</span>notfound THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'no customers selected'</span><span style="color:#666600">);</span> 
   ELSIF sql<span style="color:#666600">%</span>found THEN 
      total_rows <span style="color:#666600">:=</span> sql<span style="color:#666600">%</span>rowcount<span style="color:#666600">;</span>
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span> total_rows <span style="color:#666600">||</span> <span style="color:#008800">' customers selected '</span><span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span>  
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>      </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">6 customers selected  

PL/SQL procedure successfully completed. 
</span>

如果您检查customers表中的记录,您会发现行已更新 -

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2500.00 | 
|  2 | Khilan   |  25 | Delhi     |  2000.00 | 
|  3 | kaushik  |  23 | Kota      |  2500.00 | 
|  4 | Chaitali |  25 | Mumbai    |  7000.00 | 
|  5 | Hardik   |  27 | Bhopal    |  9000.00 | 
|  6 | Komal    |  22 | MP        |  5000.00 | 
+----+----------+-----+-----------+----------+
</span>

显式游标

显式游标是程序员定义的游标,用于获得对上下文区域的更多控制。应在PL / SQL块的声明部分中定义显式游标。它是在SELECT语句上创建的,它返回多行。

创建显式游标的语法是 -

<span style="color:#313131">CURSOR cursor_name IS select_statement; 
</span>

使用显式游标包括以下步骤 -

  • 声明游标以初始化内存
  • 打开光标以分配内存
  • 获取光标以检索数据
  • 关闭游标以释放分配的内存

声明光标

声明游标使用名称和关联的SELECT语句定义游标。例如 -

<span style="color:#313131">CURSOR c_customers IS 
   SELECT id<span style="color:#666600">,</span> name<span style="color:#666600">,</span> address FROM customers<span style="color:#666600">;</span> </span>

打开光标

打开游标会为游标分配内存,并准备好将SQL语句返回的行提取到游标中。例如,我们将按如下方式打开上面定义的游标 -

<span style="color:#313131">OPEN c_customers<span style="color:#666600">;</span> </span>

获取光标

获取光标涉及一次访问一行。例如,我们将从上面打开的游标中获取行,如下所示 -

<span style="color:#313131">FETCH c_customers INTO c_id<span style="color:#666600">,</span> c_name<span style="color:#666600">,</span> c_addr<span style="color:#666600">;</span> </span>

关闭光标

关闭光标意味着释放分配的内存。例如,我们将关闭上面打开的游标,如下所示 -

<span style="color:#313131">CLOSE c_customers<span style="color:#666600">;</span></span>

以下是一个完整的例子来说明显式游标和minua的概念;

<span style="color:#313131">DECLARE 
   c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_name customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   CURSOR c_customers <span style="color:#000088">is</span> 
      SELECT id<span style="color:#666600">,</span> name<span style="color:#666600">,</span> address FROM customers<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   OPEN c_customers<span style="color:#666600">;</span> 
   LOOP 
   FETCH c_customers <span style="color:#000088">into</span> c_id<span style="color:#666600">,</span> c_name<span style="color:#666600">,</span> c_addr<span style="color:#666600">;</span> 
      EXIT WHEN c_customers<span style="color:#666600">%</span>notfound<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>c_id <span style="color:#666600">||</span> <span style="color:#008800">' '</span> <span style="color:#666600">||</span> c_name <span style="color:#666600">||</span> <span style="color:#008800">' '</span> <span style="color:#666600">||</span> c_addr<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
   CLOSE c_customers<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">1 Ramesh Ahmedabad  
2 Khilan Delhi  
3 kaushik Kota     
4 Chaitali Mumbai  
5 Hardik Bhopal   
6 Komal MP  
  
PL/SQL procedure successfully completed. 
</span>

PL / SQL - 记录

在本章中,我们将讨论PL / SQL中的记录。一个记录是一种数据结构,可容纳不同种类的数据项。记录由不同的字段组成,类似于数据库表的一行。

例如,您希望在库中跟踪您的图书。您可能希望跟踪每本书的以下属性,例如标题,作者,主题,书籍ID。包含每个项目的字段的记录允许将BOOK视为逻辑单元,并允许您以更好的方式组织和表示其信息。

PL / SQL可以处理以下类型的记录 -

  • 基于表格的
  • 基于游标的记录
  • 用户定义的记录

基于表的记录

该ROWTYPE%属性使程序员能够创建基于表cursorbased记录。

以下示例说明了基于表的记录的概念。我们将使用我们在前面章节中创建和使用的CUSTOMERS表 -

<span style="color:#313131">DECLARE 
   customer_rec customers<span style="color:#666600">%</span>rowtype<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   SELECT <span style="color:#666600">*</span> <span style="color:#000088">into</span> customer_rec 
   FROM customers 
   WHERE id <span style="color:#666600">=</span> <span style="color:#006666">5</span><span style="color:#666600">;</span>  
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer ID: '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>id<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer Name: '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>name<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer Address: '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>address<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer Salary: '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>salary<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Customer ID: 5 
Customer Name: Hardik 
Customer Address: Bhopal 
Customer Salary: 9000 
 
PL/SQL procedure successfully completed.
</span>

基于游标的记录

以下示例说明了基于游标的记录的概念。我们将使用我们在前面章节中创建和使用的CUSTOMERS表 -

<span style="color:#313131">DECLARE 
   CURSOR customer_cur <span style="color:#000088">is</span> 
      SELECT id<span style="color:#666600">,</span> name<span style="color:#666600">,</span> address  
      FROM customers<span style="color:#666600">;</span> 
   customer_rec customer_cur<span style="color:#666600">%</span>rowtype<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   OPEN customer_cur<span style="color:#666600">;</span> 
   LOOP 
      FETCH customer_cur <span style="color:#000088">into</span> customer_rec<span style="color:#666600">;</span> 
      EXIT WHEN customer_cur<span style="color:#666600">%</span>notfound<span style="color:#666600">;</span> 
      DBMS_OUTPUT<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>customer_rec<span style="color:#666600">.</span>id <span style="color:#666600">||</span> <span style="color:#008800">' '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>name<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">1 Ramesh 
2 Khilan 
3 kaushik 
4 Chaitali 
5 Hardik 
6 Komal  

PL/SQL procedure successfully completed. 
</span>

用户定义的记录

PL / SQL提供了一个用户定义的记录类型,允许您定义不同的记录结构。这些记录包含不同的字段。假设您想要在图书馆中跟踪您的图书。您可能希望跟踪每本书的以下属性 -

  • 标题
  • 作者
  • 学科
  • 书名

定义记录

记录类型定义为 -

<span style="color:#313131">TYPE 
type_name IS RECORD 
  ( field_name1  datatype1  [NOT NULL]  [:= DEFAULT EXPRESSION], 
   field_name2   datatype2   [NOT NULL]  [:= DEFAULT EXPRESSION], 
   ... 
   field_nameN  datatypeN  [NOT NULL]  [:= DEFAULT EXPRESSION); 
record-name  type_name;
</span>

Book记录以下列方式声明 -

<span style="color:#313131">DECLARE 
TYPE books IS RECORD 
<span style="color:#666600">(</span>title  varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
   author  varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
   subject varchar<span style="color:#666600">(</span><span style="color:#006666">100</span><span style="color:#666600">),</span> 
   book_id   number<span style="color:#666600">);</span> 
book1 books<span style="color:#666600">;</span> 
book2 books<span style="color:#666600">;</span> </span>

访问字段

要访问记录的任何字段,我们使用点(。)运算符。成员访问运算符被编码为记录变量名称和我们希望访问的字段之间的句点。以下是解释记录用法的示例 -

<span style="color:#313131">DECLARE 
   type books <span style="color:#000088">is</span> record 
      <span style="color:#666600">(</span>title varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
      author varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
      subject varchar<span style="color:#666600">(</span><span style="color:#006666">100</span><span style="color:#666600">),</span> 
      book_id number<span style="color:#666600">);</span> 
   book1 books<span style="color:#666600">;</span> 
   book2 books<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600">--</span> <span style="color:#7f0055">Book</span> <span style="color:#006666">1</span> specification 
   book1<span style="color:#666600">.</span>title  <span style="color:#666600">:=</span> <span style="color:#008800">'C Programming'</span><span style="color:#666600">;</span> 
   book1<span style="color:#666600">.</span>author <span style="color:#666600">:=</span> <span style="color:#008800">'Nuha Ali '</span><span style="color:#666600">;</span>  
   book1<span style="color:#666600">.</span>subject <span style="color:#666600">:=</span> <span style="color:#008800">'C Programming Tutorial'</span><span style="color:#666600">;</span> 
   book1<span style="color:#666600">.</span>book_id <span style="color:#666600">:=</span> <span style="color:#006666">6495407</span><span style="color:#666600">;</span>  
   <span style="color:#666600">--</span> <span style="color:#7f0055">Book</span> <span style="color:#006666">2</span> specification 
   book2<span style="color:#666600">.</span>title <span style="color:#666600">:=</span> <span style="color:#008800">'Telecom Billing'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>author <span style="color:#666600">:=</span> <span style="color:#008800">'Zara Ali'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>subject <span style="color:#666600">:=</span> <span style="color:#008800">'Telecom Billing Tutorial'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>book_id <span style="color:#666600">:=</span> <span style="color:#006666">6495700</span><span style="color:#666600">;</span>  
  
  <span style="color:#666600">--</span> <span style="color:#7f0055">Print</span> book <span style="color:#006666">1</span> record 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 1 title : '</span><span style="color:#666600">||</span> book1<span style="color:#666600">.</span>title<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 1 author : '</span><span style="color:#666600">||</span> book1<span style="color:#666600">.</span>author<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 1 subject : '</span><span style="color:#666600">||</span> book1<span style="color:#666600">.</span>subject<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 1 book_id : '</span> <span style="color:#666600">||</span> book1<span style="color:#666600">.</span>book_id<span style="color:#666600">);</span> 
   
   <span style="color:#666600">--</span> <span style="color:#7f0055">Print</span> book <span style="color:#006666">2</span> record 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 2 title : '</span><span style="color:#666600">||</span> book2<span style="color:#666600">.</span>title<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 2 author : '</span><span style="color:#666600">||</span> book2<span style="color:#666600">.</span>author<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 2 subject : '</span><span style="color:#666600">||</span> book2<span style="color:#666600">.</span>subject<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 2 book_id : '</span><span style="color:#666600">||</span> book2<span style="color:#666600">.</span>book_id<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Book 1 title : C Programming 
Book 1 author : Nuha Ali 
Book 1 subject : C Programming Tutorial 
Book 1 book_id : 6495407 
Book 2 title : Telecom Billing 
Book 2 author : Zara Ali 
Book 2 subject : Telecom Billing Tutorial 
Book 2 book_id : 6495700  

PL/SQL procedure successfully completed. 
</span>

记录为子程序参数

您可以将记录作为子程序参数传递,就像传递任何其他变量一样。您也可以按照上面示例中访问的方式访问记录字段 -

<span style="color:#313131">DECLARE 
   type books <span style="color:#000088">is</span> record 
      <span style="color:#666600">(</span>title  varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
      author  varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
      subject varchar<span style="color:#666600">(</span><span style="color:#006666">100</span><span style="color:#666600">),</span> 
      book_id   number<span style="color:#666600">);</span> 
   book1 books<span style="color:#666600">;</span> 
   book2 books<span style="color:#666600">;</span>  
PROCEDURE printbook <span style="color:#666600">(</span>book books<span style="color:#666600">)</span> IS 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span><span style="color:#008800">'Book  title :  '</span> <span style="color:#666600">||</span> book<span style="color:#666600">.</span>title<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book  author : '</span> <span style="color:#666600">||</span> book<span style="color:#666600">.</span>author<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span> <span style="color:#008800">'Book  subject : '</span> <span style="color:#666600">||</span> book<span style="color:#666600">.</span>subject<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span> <span style="color:#008800">'Book book_id : '</span> <span style="color:#666600">||</span> book<span style="color:#666600">.</span>book_id<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
   
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600">--</span> <span style="color:#7f0055">Book</span> <span style="color:#006666">1</span> specification 
   book1<span style="color:#666600">.</span>title  <span style="color:#666600">:=</span> <span style="color:#008800">'C Programming'</span><span style="color:#666600">;</span> 
   book1<span style="color:#666600">.</span>author <span style="color:#666600">:=</span> <span style="color:#008800">'Nuha Ali '</span><span style="color:#666600">;</span>  
   book1<span style="color:#666600">.</span>subject <span style="color:#666600">:=</span> <span style="color:#008800">'C Programming Tutorial'</span><span style="color:#666600">;</span> 
   book1<span style="color:#666600">.</span>book_id <span style="color:#666600">:=</span> <span style="color:#006666">6495407</span><span style="color:#666600">;</span>
   
   <span style="color:#666600">--</span> <span style="color:#7f0055">Book</span> <span style="color:#006666">2</span> specification 
   book2<span style="color:#666600">.</span>title <span style="color:#666600">:=</span> <span style="color:#008800">'Telecom Billing'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>author <span style="color:#666600">:=</span> <span style="color:#008800">'Zara Ali'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>subject <span style="color:#666600">:=</span> <span style="color:#008800">'Telecom Billing Tutorial'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>book_id <span style="color:#666600">:=</span> <span style="color:#006666">6495700</span><span style="color:#666600">;</span>  
   
   <span style="color:#666600">--</span> <span style="color:#7f0055">Use</span> procedure to <span style="color:#000088">print</span> book info 
   printbook<span style="color:#666600">(</span>book1<span style="color:#666600">);</span> 
   printbook<span style="color:#666600">(</span>book2<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Book  title : C Programming 
Book  author : Nuha Ali 
Book subject : C Programming Tutorial 
Book  book_id : 6495407 
Book title : Telecom Billing 
Book author : Zara Ali 
Book subject : Telecom Billing Tutorial 
Book book_id : 6495700  

PL/SQL procedure successfully completed. 
</span>

PL / SQL - 例外

在本章中,我们将讨论PL / SQL中的异常。程序执行期间的错误条件是一个例外。PL / SQL支持程序员在程序中使用EXCEPTION块捕获这些条件,并对错误条件采取适当的操作。有两种类型的例外 -

  • 系统定义的异常
  • 用户定义的异常

异常处理的语法

异常处理的一般语法如下。在这里,您可以列出尽可能多的例外情况。默认例外将使用WHEN其他人处理- 那么 -

<span style="color:#313131">DECLARE 
   <span style="color:#666600"><</span>declarations section<span style="color:#666600">></span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600"><</span>executable command<span style="color:#666600">(</span>s<span style="color:#666600">)></span> 
EXCEPTION 
   <span style="color:#666600"><</span>exception handling goes here <span style="color:#666600">></span> 
   WHEN exception1 THEN  
      exception1<span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements  
   WHEN exception2  THEN  
      exception2<span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements  
   WHEN exception3 THEN  
      exception3<span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements 
   <span style="color:#666600">........</span> 
   WHEN others THEN 
      exception3<span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements 
<span style="color:#000088">END</span><span style="color:#666600">;</span></span>

让我们编写一个代码来说明这个概念。我们将使用我们在前面章节中创建和使用的CUSTOMERS表 -

<span style="color:#313131">DECLARE 
   c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type <span style="color:#666600">:=</span> <span style="color:#006666">8</span><span style="color:#666600">;</span> 
   c_name customerS<span style="color:#666600">.</span><span style="color:#7f0055">Name</span><span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   SELECT  name<span style="color:#666600">,</span> address INTO  c_name<span style="color:#666600">,</span> c_addr 
   FROM customers 
   WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span>  
   DBMS_OUTPUT<span style="color:#666600">.</span>PUT_LINE <span style="color:#666600">(</span><span style="color:#008800">'Name: '</span><span style="color:#666600">||</span>  c_name<span style="color:#666600">);</span> 
   DBMS_OUTPUT<span style="color:#666600">.</span>PUT_LINE <span style="color:#666600">(</span><span style="color:#008800">'Address: '</span> <span style="color:#666600">||</span> c_addr<span style="color:#666600">);</span> 

EXCEPTION 
   WHEN no_data_found THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'No such customer!'</span><span style="color:#666600">);</span> 
   WHEN others THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Error!'</span><span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">No such customer!  

PL/SQL procedure successfully completed. 
</span>

上述程序显示ID已给出的客户的名称和地址。由于我们的数据库中没有ID值为8的客户,程序会引发运行时异常NO_DATA_FOUND,该异常在EXCEPTION块中捕获。

提高例外

只要存在任何内部数据库错误,数据库服务器就会自动引发异常,但程序员可以使用命令RAISE显式引发异常。以下是引发异常的简单语法 -

<span style="color:#313131">DECLARE 
   exception_name EXCEPTION<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   IF condition THEN 
      RAISE exception_name<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
EXCEPTION 
   WHEN exception_name THEN 
   statement<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> </span>

您可以使用上述语法来引发Oracle标准异常或任何用户定义的异常。在下一节中,我们将举例说明如何引发用户定义的异常。您可以以类似的方式引发Oracle标准异常。

用户定义的异常

PL / SQL允许您根据程序的需要定义自己的异常。必须声明用户定义的异常,然后使用RAISE语句或过程DBMS_STANDARD.RAISE_APPLICATION_ERROR显式引发。

声明异常的语法是 -

<span style="color:#313131">DECLARE 
   my-exception EXCEPTION; 
</span>

以下示例说明了该概念。该程序询问客户ID,当用户输入无效ID时,引发异常invalid_id

<span style="color:#313131">DECLARE 
   c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type <span style="color:#666600">:=</span> <span style="color:#666600">&</span>cc_id<span style="color:#666600">;</span> 
   c_name customerS<span style="color:#666600">.</span><span style="color:#7f0055">Name</span><span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">;</span>  
   <span style="color:#666600">--</span> user <span style="color:#000088">defined</span> exception 
   ex_invalid_id  EXCEPTION<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   IF c_id <span style="color:#666600"><=</span> <span style="color:#006666">0</span> THEN 
      RAISE ex_invalid_id<span style="color:#666600">;</span> 
   ELSE 
      SELECT  name<span style="color:#666600">,</span> address INTO  c_name<span style="color:#666600">,</span> c_addr 
      FROM customers 
      WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span>
      DBMS_OUTPUT<span style="color:#666600">.</span>PUT_LINE <span style="color:#666600">(</span><span style="color:#008800">'Name: '</span><span style="color:#666600">||</span>  c_name<span style="color:#666600">);</span>  
      DBMS_OUTPUT<span style="color:#666600">.</span>PUT_LINE <span style="color:#666600">(</span><span style="color:#008800">'Address: '</span> <span style="color:#666600">||</span> c_addr<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 

EXCEPTION 
   WHEN ex_invalid_id THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'ID must be greater than zero!'</span><span style="color:#666600">);</span> 
   WHEN no_data_found THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'No such customer!'</span><span style="color:#666600">);</span> 
   WHEN others THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Error!'</span><span style="color:#666600">);</span>  
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Enter value for cc_id: -6 (let's enter a value -6) 
old  2: c_id customers.id%type := &cc_id; 
new  2: c_id customers.id%type := -6; 
ID must be greater than zero! 
 
PL/SQL procedure successfully completed. 
</span>

预定义的例外

PL / SQL提供了许多预定义的异常,这些异常在程序违反任何数据库规则时执行。例如,当SELECT INTO语句不返回任何行时,将引发预定义的异常NO_DATA_FOUND。下表列出了一些重要的预定义例外情况 -

例外 Oracle错误 SQLCODE 描述
ACCESS_INTO_NULL 06530 -6530 在为空对象自动分配值时引发它。
CASE_NOT_FOUND 06592 -6592 当选择CASE语句的WHEN子句中的任何选项时,并且没有ELSE子句时,将引发此问题。
COLLECTION_IS_NULL 06531 -6531 当程序尝试将除EXISTS之外的集合方法应用于未初始化的嵌套表或varray,或者程序尝试将值分配给未初始化的嵌套表或varray的元素时,将引发此问题。
DUP_VAL_ON_INDEX 00001 -1 当尝试将重复值存储在具有唯一索引的列中时,会引发此问题。
INVALID_CURSOR 01001 -1001 当尝试进行不允许的游标操作时会引发它,例如关闭未打开的游标。
无效号码 01722 -1722 当字符串转换为数字失败时会引发此错误,因为该字符串不表示有效数字。
LOGIN_DENIED 01017 -1017 当程序尝试使用无效的用户名或密码登录数据库时引发。
没有找到数据 01403 +100 当SELECT INTO语句不返回任何行时引发它。
NOT_LOGGED_ON 01012 -1012 在未连接到数据库的情况下发出数据库调用时引发此错误。
产生Program_Error 06501 -6501 当PL / SQL出现内部问题时会引发此问题。
ROWTYPE_MISMATCH 06504 -6504 当游标在具有不兼容数据类型的变量中获取值时引发它。
SELF_IS_NULL 30625 -30625 调用成员方法时引发它,但未初始化对象类型的实例。
是Storage_Error 06500 -6500 当PL / SQL内存不足或内存损坏时引发。
TOO_MANY_ROWS 01422 -1422 当SELECT INTO语句返回多行时引发它。
VALUE_ERROR 06502 -6502 发生算术,转换,截断或大小约束错误时会引发此错误。
ZERO_DIVIDE 01476 1476 当尝试将数字除以零时,会引发此问题。

PL / SQL - 触发器

在本章中,我们将讨论PL / SQL中的触发器。触发器是存储的程序,在发生某些事件时会自动执行或触发。事实上,触发器被编写为响应以下任何事件而执行 -

  • 一个数据库操作(DML)语句(DELETE,INSERT,或更新)

  • 一个数据库定义(DDL)语句(创建,变更或删除)。

  • 数据库操作(SERVERERROR,登录,注销,STARTUP,或SHUTDOWN)。

可以在与事件关联的表,视图,模式或数据库上定义触发器。

触发器的好处

可以为以下目的编写触发器 -

  • 自动生成一些派生列值
  • 实施参照完整性
  • 事件记录和存储有关表访问的信息
  • 审计
  • 表的同步复制
  • 强加安全授权
  • 防止无效的交易

创建触发器

创建触发器的语法是 -

<span style="color:#313131">CREATE <span style="color:#666600">[</span>OR REPLACE <span style="color:#666600">]</span> TRIGGER trigger_name  
<span style="color:#666600">{</span>BEFORE <span style="color:#666600">|</span> AFTER <span style="color:#666600">|</span> INSTEAD OF <span style="color:#666600">}</span>  
<span style="color:#666600">{</span>INSERT <span style="color:#666600">[</span>OR<span style="color:#666600">]</span> <span style="color:#666600">|</span> UPDATE <span style="color:#666600">[</span>OR<span style="color:#666600">]</span> <span style="color:#666600">|</span> DELETE<span style="color:#666600">}</span>  
<span style="color:#666600">[</span>OF col_name<span style="color:#666600">]</span>  
ON table_name  
<span style="color:#666600">[</span>REFERENCING OLD AS o NEW AS n<span style="color:#666600">]</span>  
<span style="color:#666600">[</span>FOR EACH ROW<span style="color:#666600">]</span>  
WHEN <span style="color:#666600">(</span>condition<span style="color:#666600">)</span>   
DECLARE 
   <span style="color:#7f0055">Declaration</span><span style="color:#666600">-</span>statements 
<span style="color:#000088">BEGIN</span>  
   <span style="color:#7f0055">Executable</span><span style="color:#666600">-</span>statements 
EXCEPTION 
   <span style="color:#7f0055">Exception</span><span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements 
<span style="color:#000088">END</span><span style="color:#666600">;</span> </span>

哪里,

  • CREATE [OR REPLACE] TRIGGER TRIGGER_NAME -创建或与替换现有触发TRIGGER_NAME

  • {BEFORE | 之后| INSTEAD OF} - 指定何时执行触发器。INSTEAD OF子句用于在视图上创建触发器。

  • {INSERT [OR] | 更新[或] | DELETE} - 这指定了DML操作。

  • [OF col_name] - 指定要更新的列名。

  • [ON table_name] - 指定与触发器关联的表的名称。

  • [引用旧的as n n] - 这允许您为各种DML语句引用新值和旧值,例如INSERT,UPDATE和DELETE。

  • [FOR EACH ROW] - 指定行级触发器,即将对受影响的每一行执行触发器。否则,触发器将在执行SQL语句时执行一次,这称为表级触发器。

  • WHEN(条件) - 这为触发器将触发的行提供条件。该子句仅对行级触发器有效。

首先,我们将使用我们在前几章中创建和使用的CUSTOMERS表 -

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+ 
</span>

以下程序为customers表创建行级触发器,该触发器将针对在CUSTOMERS表上执行的INSERT或UPDATE或DELETE操作触发。此触发器将显示旧值和新值之间的工资差异 -

<span style="color:#313131">CREATE OR REPLACE TRIGGER display_salary_changes 
BEFORE DELETE OR INSERT OR UPDATE ON customers 
FOR EACH ROW 
WHEN <span style="color:#666600">(</span>NEW<span style="color:#666600">.</span>ID <span style="color:#666600">></span> <span style="color:#006666">0</span><span style="color:#666600">)</span> 
DECLARE 
   sal_diff number<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   sal_diff <span style="color:#666600">:=</span> <span style="color:#666600">:</span>NEW<span style="color:#666600">.</span>salary  <span style="color:#666600">-</span> <span style="color:#666600">:</span>OLD<span style="color:#666600">.</span>salary<span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Old salary: '</span> <span style="color:#666600">||</span> <span style="color:#666600">:</span>OLD<span style="color:#666600">.</span>salary<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'New salary: '</span> <span style="color:#666600">||</span> <span style="color:#666600">:</span>NEW<span style="color:#666600">.</span>salary<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Salary difference: '</span> <span style="color:#666600">||</span> sal_diff<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Trigger created.
</span>

这里需要考虑以下几点 -

  • OLD和NEW引用不适用于表级触发器,而是可以将它们用于记录级触发器。

  • 如果要在同一触发器中查询表,则应使用AFTER关键字,因为触发器只能在应用初始更改并且表恢复到一致状态后才能查询表或再次更改表。

  • 上面的触发器是以这样的方式编写的,它会在对表执行任何DELETE或INSERT或UPDATE操作之前触发,但是您可以在单个或多个操作上编写触发器,例如BEFORE DELETE,它将在记录时触发将使用表上的DELETE操作删除。

触发触发器

让我们在CUSTOMERS表上执行一些DML操作。这是一个INSERT语句,它将在表中创建一条新记录 -

<span style="color:#313131">INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#008800">'Kriti'</span><span style="color:#666600">,</span> <span style="color:#006666">22</span><span style="color:#666600">,</span> <span style="color:#008800">'HP'</span><span style="color:#666600">,</span> <span style="color:#006666">7500.00</span> <span style="color:#666600">);</span> </span>

当在CUSTOMERS表中创建记录时,将触发上面的创建触发器display_salary_changes,它将显示以下结果 -

<span style="color:#313131">Old salary: 
New salary: 7500 
Salary difference:
</span>

因为这是一个新记录,旧工资不可用,上述结果为空。现在让我们在CUSTOMERS表上再执行一次DML操作。UPDATE语句将更新表中的现有记录 -

<span style="color:#313131">UPDATE customers 
SET salary <span style="color:#666600">=</span> salary <span style="color:#666600">+</span> <span style="color:#006666">500</span> 
WHERE id <span style="color:#666600">=</span> <span style="color:#006666">2</span><span style="color:#666600">;</span> </span>

当在CUSTOMERS表中更新记录时,将触发上述创建触发器display_salary_changes,它将显示以下结果 -

<span style="color:#313131">Old salary: 1500 
New salary: 2000 
Salary difference: 500 
</span>

PL / SQL - 包

在本章中,我们将讨论PL / SQL中的包。包是模式对象,用于对逻辑上相关的PL / SQL类型,变量和子程序进行分组。

一个包将有两个强制部分 -

  • 包装规格
  • 包体或定义

包装规格

规范是包的接口。它只是声明可以从包外部引用的类型,变量,常量,异常,游标和子程序。换句话说,它包含有关包内容的所有信息,但不包括子程序的代码。

放在规范中的所有对象都称为公共对象。任何不在包规范中但在包体中编码的子程序称为私有对象。

以下代码段显示了具有单个过程的包规范。您可以定义许多全局变量,并在包中包含多个过程或函数。

<span style="color:#313131">CREATE PACKAGE cust_sal AS 
   PROCEDURE find_sal<span style="color:#666600">(</span>c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">);</span> 
<span style="color:#000088">END</span> cust_sal<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Package created.
</span>

包体

包体具有包规范中声明的各种方法的代码和其他私有声明,这些声明对包外的代码是隐藏的。

CREATE PACKAGE BODY语句用于创建包体。以下代码段显示了上面创建的cust_sal包的包体声明。我假设我们已经在PL / SQL - Variables章节中提到的数据库中创建了CUSTOMERS表。

<span style="color:#313131">CREATE OR REPLACE PACKAGE BODY cust_sal AS  
   
   PROCEDURE find_sal<span style="color:#666600">(</span>c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>TYPE<span style="color:#666600">)</span> IS 
   c_sal customers<span style="color:#666600">.</span>salary<span style="color:#666600">%</span>TYPE<span style="color:#666600">;</span> 
   <span style="color:#000088">BEGIN</span> 
      SELECT salary INTO c_sal 
      FROM customers 
      WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Salary: '</span><span style="color:#666600">||</span> c_sal<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> find_sal<span style="color:#666600">;</span> 
<span style="color:#000088">END</span> cust_sal<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Package body created.
</span>

使用包元素

使用以下语法访问包元素(变量,过程或函数) -

<span style="color:#313131">package_name.element_name;
</span>

考虑一下,我们已经在我们的数据库模式中创建了上面的包,下面的程序使用了cust_sal包的find_sal方法-

<span style="color:#313131">DECLARE 
   code customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type <span style="color:#666600">:=</span> <span style="color:#666600">&</span>cc_id<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   cust_sal<span style="color:#666600">.</span>find_sal<span style="color:#666600">(</span>code<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会提示输入客户ID,当您输入ID时,它会显示相应的工资,如下所示 -

<span style="color:#313131">Enter value for cc_id: 1 
Salary: 3000 

PL/SQL procedure successfully completed. 
</span>

以下程序提供了更完整的包。我们将使用存储在我们数据库中的CUSTOMERS表,其中包含以下记录 -

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  3000.00 | 
|  2 | Khilan   |  25 | Delhi     |  3000.00 | 
|  3 | kaushik  |  23 | Kota      |  3000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  7500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  9500.00 | 
|  6 | Komal    |  22 | MP        |  5500.00 | 
+----+----------+-----+-----------+----------+
</span>

包装规格

<span style="color:#313131">CREATE OR REPLACE PACKAGE c_package AS 
   <span style="color:#666600">--</span> <span style="color:#7f0055">Adds</span> a customer 
   PROCEDURE addCustomer<span style="color:#666600">(</span>c_id   customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
   c_name  customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
   c_age  customers<span style="color:#666600">.</span>age<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">,</span>  
   c_sal  customers<span style="color:#666600">.</span>salary<span style="color:#666600">%</span>type<span style="color:#666600">);</span> 
   
   <span style="color:#666600">--</span> <span style="color:#7f0055">Removes</span> a customer 
   PROCEDURE delCustomer<span style="color:#666600">(</span>c_id  customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>TYPE<span style="color:#666600">);</span> 
   <span style="color:#666600">--</span><span style="color:#7f0055">Lists</span> all customers 
   PROCEDURE listCustomer<span style="color:#666600">;</span> 
  
<span style="color:#000088">END</span> c_package<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会创建上述包并显示以下结果 -

<span style="color:#313131">Package created.
</span>

创建包体

<span style="color:#313131">CREATE OR REPLACE PACKAGE BODY c_package AS 
   PROCEDURE addCustomer<span style="color:#666600">(</span>c_id  customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
      c_name customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
      c_age  customers<span style="color:#666600">.</span>age<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
      c_addr  customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">,</span>  
      c_sal   customers<span style="color:#666600">.</span>salary<span style="color:#666600">%</span>type<span style="color:#666600">)</span> 
   IS 
   <span style="color:#000088">BEGIN</span> 
      INSERT INTO customers <span style="color:#666600">(</span>id<span style="color:#666600">,</span>name<span style="color:#666600">,</span>age<span style="color:#666600">,</span>address<span style="color:#666600">,</span>salary<span style="color:#666600">)</span> 
         VALUES<span style="color:#666600">(</span>c_id<span style="color:#666600">,</span> c_name<span style="color:#666600">,</span> c_age<span style="color:#666600">,</span> c_addr<span style="color:#666600">,</span> c_sal<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> addCustomer<span style="color:#666600">;</span> 
   
   PROCEDURE delCustomer<span style="color:#666600">(</span>c_id   customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">)</span> IS 
   <span style="color:#000088">BEGIN</span> 
      DELETE FROM customers 
      WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> delCustomer<span style="color:#666600">;</span>  
   
   PROCEDURE listCustomer IS 
   CURSOR c_customers <span style="color:#000088">is</span> 
      SELECT  name FROM customers<span style="color:#666600">;</span> 
   TYPE c_list <span style="color:#000088">is</span> TABLE OF customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   name_list c_list <span style="color:#666600">:=</span> c_list<span style="color:#666600">();</span> 
   counter integer <span style="color:#666600">:=</span><span style="color:#006666">0</span><span style="color:#666600">;</span> 
   <span style="color:#000088">BEGIN</span> 
      FOR n IN c_customers LOOP 
      counter <span style="color:#666600">:=</span> counter <span style="color:#666600">+</span><span style="color:#006666">1</span><span style="color:#666600">;</span> 
      name_list<span style="color:#666600">.</span>extend<span style="color:#666600">;</span> 
      name_list<span style="color:#666600">(</span>counter<span style="color:#666600">)</span> <span style="color:#666600">:=</span> n<span style="color:#666600">.</span>name<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer('</span> <span style="color:#666600">||</span>counter<span style="color:#666600">||</span> <span style="color:#008800">')'</span><span style="color:#666600">||</span>name_list<span style="color:#666600">(</span>counter<span style="color:#666600">));</span> 
      <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> listCustomer<span style="color:#666600">;</span>
   
<span style="color:#000088">END</span> c_package<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

上面的示例使用嵌套表。我们将在下一章讨论嵌套表的概念。

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Package body created.
</span>

使用包

以下程序使用包c_package中声明和定义的方法。

<span style="color:#313131">DECLARE 
   code customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">:=</span> <span style="color:#006666">8</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   c_package<span style="color:#666600">.</span>addcustomer<span style="color:#666600">(</span><span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#008800">'Rajnish'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Chennai'</span><span style="color:#666600">,</span> <span style="color:#006666">3500</span><span style="color:#666600">);</span> 
   c_package<span style="color:#666600">.</span>addcustomer<span style="color:#666600">(</span><span style="color:#006666">8</span><span style="color:#666600">,</span> <span style="color:#008800">'Subham'</span><span style="color:#666600">,</span> <span style="color:#006666">32</span><span style="color:#666600">,</span> <span style="color:#008800">'Delhi'</span><span style="color:#666600">,</span> <span style="color:#006666">7500</span><span style="color:#666600">);</span> 
   c_package<span style="color:#666600">.</span>listcustomer<span style="color:#666600">;</span> 
   c_package<span style="color:#666600">.</span>delcustomer<span style="color:#666600">(</span>code<span style="color:#666600">);</span> 
   c_package<span style="color:#666600">.</span>listcustomer<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal 
Customer(7): Rajnish 
Customer(8): Subham 
Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal
Customer(7): Rajnish 

PL/SQL procedure successfully completed 
</span>

PL / SQL - 集合

在本章中,我们将讨论PL / SQL中的集合。集合是具有相同数据类型的有序元素组。每个元素由唯一的下标标识,该下标表示其在集合中的位置。

PL / SQL提供三种集合类型 -

  • 索引表或关联数组
  • 嵌套表
  • 可变大小的数组或Varray

Oracle文档为每种类型的集合提供以下特征 -

收集类型 元素数量 下标类型 密集或稀疏 在哪里创建 可以是对象类型属性
关联数组(或索引表) 无界 字符串或整数 仅在PL / SQL块中 没有
嵌套表 无界 整数 开始密集,可以变得稀疏 在PL / SQL块或模式级别
Variablesize数组(Varray) 有界 整数 总是密集的 在PL / SQL块或模式级别

我们已经在“PL / SQL数组”一章中讨论了varray 。在本章中,我们将讨论PL / SQL表。

两种类型的PL / SQL表,即索引表和嵌套表具有相同的结构,并且使用下标表示法访问它们的行。但是,这两种表格在一个方面有所不同; 嵌套表可以存储在数据库列中,而索引表则不能。

索引 - 按表

一个索引由表(也称为关联数组)是一组的键-值对。每个键都是唯一的,用于定位相应的值。密钥可以是整数或字符串。

使用以下语法创建索引表。在这里,我们创建一个名为table_name索引表,其中的键将是subscript_type,关联的值将是element_type

<span style="color:#313131">TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY subscript_type; 
 
table_name type_name;
</span>

下面的示例演示如何创建一个表来存储整数值以及名称,然后打印相同的名称列表。

<span style="color:#313131">DECLARE 
   TYPE salary IS TABLE OF NUMBER INDEX BY VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">);</span> 
   salary_list salary<span style="color:#666600">;</span> 
   name   VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600">--</span> adding elements to the table 
   salary_list<span style="color:#666600">(</span><span style="color:#008800">'Rajnish'</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">62000</span><span style="color:#666600">;</span> 
   salary_list<span style="color:#666600">(</span><span style="color:#008800">'Minakshi'</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">75000</span><span style="color:#666600">;</span> 
   salary_list<span style="color:#666600">(</span><span style="color:#008800">'Martin'</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">100000</span><span style="color:#666600">;</span> 
   salary_list<span style="color:#666600">(</span><span style="color:#008800">'James'</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">78000</span><span style="color:#666600">;</span>  
   
   <span style="color:#666600">--</span> printing the table 
   name <span style="color:#666600">:=</span> salary_list<span style="color:#666600">.</span>FIRST<span style="color:#666600">;</span> 
   WHILE name IS NOT <span style="color:#000088">null</span> LOOP 
      dbms_output<span style="color:#666600">.</span>put_line 
      <span style="color:#666600">(</span><span style="color:#008800">'Salary of '</span> <span style="color:#666600">||</span> name <span style="color:#666600">||</span> <span style="color:#008800">' is '</span> <span style="color:#666600">||</span> TO_CHAR<span style="color:#666600">(</span>salary_list<span style="color:#666600">(</span>name<span style="color:#666600">)));</span> 
      name <span style="color:#666600">:=</span> salary_list<span style="color:#666600">.</span>NEXT<span style="color:#666600">(</span>name<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Salary of James is 78000 
Salary of Martin is 100000 
Salary of Minakshi is 75000 
Salary of Rajnish is 62000  

PL/SQL procedure successfully completed.
</span>

索引表的元素也可以是任何数据库表的%ROWTYPE或任何数据库表字段的%TYPE。以下示例说明了该概念。我们将使用存储在我们数据库中的CUSTOMERS表作为 -

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+  
</span>

 

<span style="color:#313131">DECLARE 
   CURSOR c_customers <span style="color:#000088">is</span> 
      <span style="color:#000088">select</span> name <span style="color:#000088">from</span> customers<span style="color:#666600">;</span> 

   TYPE c_list IS TABLE of customers<span style="color:#666600">.</span><span style="color:#7f0055">Name</span><span style="color:#666600">%</span>type INDEX BY binary_integer<span style="color:#666600">;</span> 
   name_list c_list<span style="color:#666600">;</span> 
   counter integer <span style="color:#666600">:=</span><span style="color:#006666">0</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   FOR n IN c_customers LOOP 
      counter <span style="color:#666600">:=</span> counter <span style="color:#666600">+</span><span style="color:#006666">1</span><span style="color:#666600">;</span> 
      name_list<span style="color:#666600">(</span>counter<span style="color:#666600">)</span> <span style="color:#666600">:=</span> n<span style="color:#666600">.</span>name<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer('</span><span style="color:#666600">||</span>counter<span style="color:#666600">||</span><span style="color:#008800">'):'</span><span style="color:#666600">||</span>name_lis t<span style="color:#666600">(</span>counter<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal  

PL/SQL procedure successfully completed
</span>

嵌套表

嵌套表是像元素的任意数量的一维数组。但是,嵌套表在以下方面与数组不同 -

  • 数组具有声明的元素数,但嵌套表不具有。嵌套表的大小可以动态增加。

  • 数组总是密集的,即它总是有连续的下标。嵌套数组最初是密集的,但是当从中删除元素时,它可能变得稀疏。

使用以下语法创建嵌套表 -

<span style="color:#313131">TYPE type_name IS TABLE OF element_type [NOT NULL]; 
 
table_name type_name; 
</span>

此声明类似于索引表的声明,但没有INDEX BY子句。

嵌套表可以存储在数据库列中。它可以进一步用于简化SQL操作,其中您使用较大的表连接单列表。关联数组不能存储在数据库中。

以下示例说明了嵌套表的使用 -

<span style="color:#313131">DECLARE 
   TYPE names_table IS TABLE OF VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">);</span> 
   TYPE grades IS TABLE OF INTEGER<span style="color:#666600">;</span>  
   names names_table<span style="color:#666600">;</span> 
   marks grades<span style="color:#666600">;</span> 
   total integer<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   names <span style="color:#666600">:=</span> names_table<span style="color:#666600">(</span><span style="color:#008800">'Kavita'</span><span style="color:#666600">,</span> <span style="color:#008800">'Pritam'</span><span style="color:#666600">,</span> <span style="color:#008800">'Ayan'</span><span style="color:#666600">,</span> <span style="color:#008800">'Rishav'</span><span style="color:#666600">,</span> <span style="color:#008800">'Aziz'</span><span style="color:#666600">);</span> 
   marks<span style="color:#666600">:=</span> grades<span style="color:#666600">(</span><span style="color:#006666">98</span><span style="color:#666600">,</span> <span style="color:#006666">97</span><span style="color:#666600">,</span> <span style="color:#006666">78</span><span style="color:#666600">,</span> <span style="color:#006666">87</span><span style="color:#666600">,</span> <span style="color:#006666">92</span><span style="color:#666600">);</span> 
   total <span style="color:#666600">:=</span> names<span style="color:#666600">.</span>count<span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Total '</span><span style="color:#666600">||</span> total <span style="color:#666600">||</span> <span style="color:#008800">' Students'</span><span style="color:#666600">);</span> 
   FOR i IN <span style="color:#006666">1</span> <span style="color:#666600">..</span> total LOOP 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Student:'</span><span style="color:#666600">||</span>names<span style="color:#666600">(</span>i<span style="color:#666600">)||</span><span style="color:#008800">', Marks:'</span> <span style="color:#666600">||</span> marks<span style="color:#666600">(</span>i<span style="color:#666600">));</span> 
   <span style="color:#000088">end</span> loop<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Total 5 Students 
Student:Kavita, Marks:98 
Student:Pritam, Marks:97 
Student:Ayan, Marks:78 
Student:Rishav, Marks:87 
Student:Aziz, Marks:92  

PL/SQL procedure successfully completed. 
</span>

嵌套表的元素也可以是任何数据库表的%ROWTYPE或任何数据库表字段的%TYPE。以下示例说明了该概念。我们将使用存储在我们数据库中的CUSTOMERS表作为 -

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+ 
</span>

 

<span style="color:#313131">DECLARE 
   CURSOR c_customers <span style="color:#000088">is</span>  
      SELECT  name FROM customers<span style="color:#666600">;</span>  
   TYPE c_list IS TABLE of customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   name_list c_list <span style="color:#666600">:=</span> c_list<span style="color:#666600">();</span> 
   counter integer <span style="color:#666600">:=</span><span style="color:#006666">0</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   FOR n IN c_customers LOOP 
      counter <span style="color:#666600">:=</span> counter <span style="color:#666600">+</span><span style="color:#006666">1</span><span style="color:#666600">;</span> 
      name_list<span style="color:#666600">.</span>extend<span style="color:#666600">;</span> 
      name_list<span style="color:#666600">(</span>counter<span style="color:#666600">)</span>  <span style="color:#666600">:=</span> n<span style="color:#666600">.</span>name<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer('</span><span style="color:#666600">||</span>counter<span style="color:#666600">||</span><span style="color:#008800">'):'</span><span style="color:#666600">||</span>name_list<span style="color:#666600">(</span>counter<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal  

PL/SQL procedure successfully completed. 
</span>

收集方法

PL / SQL提供了内置的集合方法,使集合更易于使用。下表列出了方法及其用途 -

S.No 方法名称和目的
1

EXISTS(N)

如果集合中的第n个元素存在,则返回TRUE; 否则返回FALSE。

2

计数

返回集合当前包含的元素数。

3

限制

检查集合的最大大小。

4

第一

返回使用整数下标的集合中的第一个(最小)索引号。

持续

返回使用整数下标的集合中的最后(最大)索引号。

6

PRIOR(N)

返回集合中索引n之前的索引号。

7

NEXT(N)

返回索引n后的索引号。

8

延伸

将一个null元素追加到集合中。

9

EXTEND(N)

将n个null元素追加到集合中。

10

EXTEND(N,I)

将第i 个元素的n个副本追加到集合中。

11

修剪

从集合的末尾删除一个元素。

12

TRIM(N)

从集合末尾删除n个元素。

13

删除

从集合中删除所有元素,将COUNT设置为0。

14

DELETE(N)

使用数字键或嵌套表从关联数组中删除第n 个元素。如果关联数组具有字符串键,则删除与键值对应的元素。如果n为null,则DELETE(n)不执行任何操作。

15

DELETE(M,N)

从关联数组或嵌套表中删除m..n范围内的所有元素。如果m大于nmn为null,则DELETE(m,n)不执行任何操作。

收集例外

下表提供了集合异常以及何时引发它们 -

收集例外 在情境中提升
COLLECTION_IS_NULL 您尝试操作原子空集合。
没有找到数据 下标指定已删除的元素,或关联数组的不存在元素。
SUBSCRIPT_BEYOND_COUNT 下标超过集合中的元素数。
SUBSCRIPT_OUTSIDE_LIMIT 下标超出允许范围。
VALUE_ERROR 下标为null或不可转换为键类型。如果将键定义为PLS_INTEGER范围,并且下标超出此范围,则可能会发生此异常。

PL / SQL - 交易

在本章中,我们将讨论PL / SQL中的事务。数据库事务是一个原子工作单元,可能包含一个或多个相关的SQL语句。它被称为原子,因为构成事务的SQL语句带来的数据库修改可以共同提交,即对数据库永久保留或从数据库回滚(撤消)。

成功执行的SQL语句和已提交的事务不相同。即使成功执行了SQL语句,除非提交包含该语句的事务,否则可以回滚该语句,并且可以撤消语句所做的所有更改。

开始和结束交易

交易有开始结束。当发生以下事件之一时,交易开始 -

  • 连接到数据库后执行第一个SQL语句。

  • 在事务完成后发出的每个新SQL语句。

当发生以下事件之一时,交易结束 -

  • 一个COMMITROLLBACK语句发出。

  • 一个DDL语句,比如CREATE TABLE语句,则发出; 因为在这种情况下会自动执行COMMIT。

  • 发布DCL语句,例如GRANT语句; 因为在这种情况下会自动执行COMMIT。

  • 用户断开与数据库的连接。

  • 用户通过发出EXIT命令退出SQL * PLUS,自动执行COMMIT。

  • SQL * Plus异常终止,自动执行ROLLBACK

  • 一个DML语句失败; 在这种情况下,会自动执行ROLLBACK来撤消该DML语句。

提交交易

通过发出SQL命令COMMIT使事务成为永久事务。COMMIT命令的一般语法是 -

<span style="color:#313131">COMMIT;
</span>

例如,

<span style="color:#313131">INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">,</span> <span style="color:#008800">'Ramesh'</span><span style="color:#666600">,</span> <span style="color:#006666">32</span><span style="color:#666600">,</span> <span style="color:#008800">'Ahmedabad'</span><span style="color:#666600">,</span> <span style="color:#006666">2000.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">,</span> <span style="color:#008800">'Khilan'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Delhi'</span><span style="color:#666600">,</span> <span style="color:#006666">1500.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">,</span> <span style="color:#008800">'kaushik'</span><span style="color:#666600">,</span> <span style="color:#006666">23</span><span style="color:#666600">,</span> <span style="color:#008800">'Kota'</span><span style="color:#666600">,</span> <span style="color:#006666">2000.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">4</span><span style="color:#666600">,</span> <span style="color:#008800">'Chaitali'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Mumbai'</span><span style="color:#666600">,</span> <span style="color:#006666">6500.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span> <span style="color:#008800">'Hardik'</span><span style="color:#666600">,</span> <span style="color:#006666">27</span><span style="color:#666600">,</span> <span style="color:#008800">'Bhopal'</span><span style="color:#666600">,</span> <span style="color:#006666">8500.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">6</span><span style="color:#666600">,</span> <span style="color:#008800">'Komal'</span><span style="color:#666600">,</span> <span style="color:#006666">22</span><span style="color:#666600">,</span> <span style="color:#008800">'MP'</span><span style="color:#666600">,</span> <span style="color:#006666">4500.00</span> <span style="color:#666600">);</span> 

COMMIT<span style="color:#666600">;</span></span>

回滚交易

使用ROLLBACK命令可以撤消对没有COMMIT的数据库所做的更改。

ROLLBACK命令的一般语法是 -

<span style="color:#313131">ROLLBACK [TO SAVEPOINT < savepoint_name>]; 
</span>

当事务因某些前所未有的情况(例如系统故障)而中止时,自提交以来的整个事务将自动回滚。如果您没有使用savepoint,那么只需使用以下语句来回滚所有更改 -

<span style="color:#313131">ROLLBACK;
</span>

保存点

保存点是一种标记,有助于通过设置一些检查点将长事务拆分为更小的单元。通过在长事务中设置保存点,您可以根据需要回滚到检查点。这是通过发出SAVEPOINT命令完成的。

SAVEPOINT命令的一般语法是 -

<span style="color:#313131">SAVEPOINT < savepoint_name >;
</span>

例如

<span style="color:#313131">INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#008800">'Rajnish'</span><span style="color:#666600">,</span> <span style="color:#006666">27</span><span style="color:#666600">,</span> <span style="color:#008800">'HP'</span><span style="color:#666600">,</span> <span style="color:#006666">9500.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">8</span><span style="color:#666600">,</span> <span style="color:#008800">'Riddhi'</span><span style="color:#666600">,</span> <span style="color:#006666">21</span><span style="color:#666600">,</span> <span style="color:#008800">'WB'</span><span style="color:#666600">,</span> <span style="color:#006666">4500.00</span> <span style="color:#666600">);</span> 
SAVEPOINT sav1<span style="color:#666600">;</span>
  
UPDATE CUSTOMERS 
SET SALARY <span style="color:#666600">=</span> SALARY <span style="color:#666600">+</span> <span style="color:#006666">1000</span><span style="color:#666600">;</span> 
ROLLBACK TO sav1<span style="color:#666600">;</span>
  
UPDATE CUSTOMERS 
SET SALARY <span style="color:#666600">=</span> SALARY <span style="color:#666600">+</span> <span style="color:#006666">1000</span> 
WHERE ID <span style="color:#666600">=</span> <span style="color:#006666">7</span><span style="color:#666600">;</span> 
UPDATE CUSTOMERS 
SET SALARY <span style="color:#666600">=</span> SALARY <span style="color:#666600">+</span> <span style="color:#006666">1000</span> 
WHERE ID <span style="color:#666600">=</span> <span style="color:#006666">8</span><span style="color:#666600">;</span> 

COMMIT<span style="color:#666600">;</span></span>

ROLLBACK TO sav1 - 此语句将所有更改回滚到您已标记为savepoint sav1的位置。

之后,您所做的新更改将开始。

自动交易控制

要在执行INSERT,UPDATEDELETE命令时自动执行COMMIT,可以将AUTOCOMMIT环境变量设置为 -

<span style="color:#313131">SET AUTOCOMMIT ON; 
</span>

您可以使用以下命令关闭自动提交模式 -

<span style="color:#313131">SET AUTOCOMMIT OFF;
</span>

PL / SQL - 日期和时间

在本章中,我们将讨论PL / SQL中的日期和时间。PL / SQL中有两类与日期和时间相关的数据类型 -

  • 日期时间数据类型
  • 区间数据类型

Datetime数据类型是 -

  • 日期
  • TIMESTAMP
  • TIMESTAMP与时区
  • TIMESTAMP与当地时区

Interval数据类型是 -

  • 间隔年至月
  • 间隔第二天

日期时间和间隔数据类型的字段值

两个日期时间时间间隔的数据类型包括字段。这些字段的值确定数据类型的值。下表列出了日期时间和间隔的字段及其可能的值。

字段名称 有效的日期时间值 有效间隔值
-4712至9999(不包括0年) 任何非零整数
01至12 0到11
01到31(根据区域设置的日历规则,受MONTH和YEAR的值限制) 任何非零整数
小时 00至23 0到23
分钟 00至59 0到59
第二

00至59.9(n),其中9(n)是时间分数秒的精度

9(n)部分不适用于DATE。

0到59.9(n),其中9(n)是区间小数秒的精度
TIMEZONE_HOUR

-12至14(范围适应夏令时变化)

不适用于DATE或TIMESTAMP。

不适用
TIMEZONE_MINUTE

00至59

不适用于DATE或TIMESTAMP。

不适用
TIMEZONE_REGION 不适用于DATE或TIMESTAMP。 不适用
TIMEZONE_ABBR 不适用于DATE或TIMESTAMP。 不适用

日期时间数据类型和函数

以下是Datetime数据类型 -

日期

它以字符和数字数据类型存储日期和时间信息。它由世纪,年,月,日,小时,分钟和秒组成。它被指定为 -

TIMESTAMP

它是DATE数据类型的扩展。它存储DATE数据类型的年,月和日,以及小时,分钟和秒值。它对于存储精确的时间值很有用。

TIMESTAMP与时区

它是TIMESTAMP的变体,包括时区区域名称或其值的时区偏移量。时区偏移量是本地时间和UTC之间的差异(以小时和分钟为单位)。此数据类型可用于收集和评估跨地理区域的日期信息。

TIMESTAMP与当地时区

它是TIMESTAMP的另一个变体,其值包含时区偏移量。

下表提供了Datetime函数(其中,x具有datetime值) -

S.No 功能名称和描述
1

ADD_MONTHS(x,y);

x个月添加到x

2

LAST_DAY(X);

返回该月的最后一天。

3

MONTHS_BETWEEN(x,y);

返回xy之间的月数。

4

NEXT_DAY(x,day);

返回x后第二天的日期时间。

NEW_TIME;

返回用户指定的时区的时间/日期值。

6

ROUND(x [,unit]);

x

7

SYSDATE();

返回当前日期时间。

8

TRUNC(x [,unit]);

截断x

时间戳功能(其中,x具有时间戳值) -

S.No 功能名称和描述
1

CURRENT_TIMESTAMP();

返回包含当前会话时间和会话时区的TIMESTAMP WITH TIME ZONE。

2

提取({年|月|日|小时|分钟|第二} | {TIMEZONE_HOUR | TIMEZONE_MINUTE} | {TIMEZONE_REGION |} TIMEZONE_ABBR)FROM x)

x中提取并返回年,月,日,小时,分钟,秒或时区。

3

FROM_TZ(x,time_zone);

将TIMESTAMP x和time_zone指定的时区转换为TIMESTAMP WITH TIMEZONE。

4

LOCALTIMESTAMP();

返回包含会话时区中的本地时间的TIMESTAMP。

SYSTIMESTAMP();

返回包含当前数据库时间和数据库时区的TIMESTAMP WITH TIME ZONE。

6

SYS_EXTRACT_UTC(X);

将TIMESTAMP WITH TIMEZONE x转换为包含UTC日期和时间的TIMESTAMP。

7

TO_TIMESTAMP(x,[format]);

将字符串x转换为TIMESTAMP。

8

TO_TIMESTAMP_TZ(x,[format]);

将字符串x转换为TIMESTAMP WITH TIMEZONE。

例子

以下代码片段说明了上述功能的使用 -

例1

<span style="color:#313131">SELECT SYSDATE FROM DUAL<span style="color:#666600">;</span> </span>

输出 -

<span style="color:#313131">08/31/2012 5:25:34 PM 
</span>

例2

<span style="color:#313131">SELECT TO_CHAR<span style="color:#666600">(</span>CURRENT_DATE<span style="color:#666600">,</span> <span style="color:#008800">'DD-MM-YYYY HH:MI:SS'</span><span style="color:#666600">)</span> FROM DUAL<span style="color:#666600">;</span> </span>

输出 -

<span style="color:#313131">31-08-2012 05:26:14
</span>

例3

<span style="color:#313131">SELECT ADD_MONTHS<span style="color:#666600">(</span>SYSDATE<span style="color:#666600">,</span> <span style="color:#006666">5</span><span style="color:#666600">)</span> FROM DUAL<span style="color:#666600">;</span></span>

输出 -

<span style="color:#313131">01/31/2013 5:26:31 PM 
</span>

例4

<span style="color:#313131">SELECT LOCALTIMESTAMP FROM DUAL<span style="color:#666600">;</span> </span>

输出 -

<span style="color:#313131">8/31/2012 5:26:55.347000 PM 
</span>

区间数据类型和功能

以下是Interval数据类型 -

  • IINTERVAL年至月 - 它使用YEAR和MONTH日期时间字段存储一段时间。

  • INTERVAL DAY TO SECOND - 它以天,小时,分钟和秒为单位存储一段时间。

区间函数

S.No 功能名称和描述
1

NUMTODSINTERVAL(x,interval_unit);

将数字x转换为INTERVAL DAY TO SECOND。

2

NUMTOYMINTERVAL(x,interval_unit);

将数字x转换为INTERVAL YEAR TO MONTH。

3

TO_DSINTERVAL(X);

将字符串x转换为INTERVAL DAY TO SECOND。

4

TO_YMINTERVAL(X);

将字符串x转换为INTERVAL YEAR TO MONTH。

PL / SQL - DBMS输出

在本章中,我们将讨论PL / SQL中的DBMS输出。该DBMS_OUTPUT是一个内置的包,它使您可以显示输出,调试信息,并从PL / SQL块,子程序,包和触发器发送消息。我们已经在整个教程中使用了这个包。

让我们看一个小代码片段,它将显示数据库中的所有用户表。在您的数据库中尝试它以列出所有表名 -

<span style="color:#313131"><span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line  <span style="color:#666600">(</span>user <span style="color:#666600">||</span> <span style="color:#008800">' Tables in the database:'</span><span style="color:#666600">);</span> 
   FOR t IN <span style="color:#666600">(</span>SELECT table_name FROM user_tables<span style="color:#666600">)</span> 
   LOOP 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>t<span style="color:#666600">.</span>table_name<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

DBMS_OUTPUT子程序

DBMS_OUTPUT包具有以下子程序 -

S.No 子程序和目的
1

DBMS_OUTPUT.DISABLE;

禁用消息输出。

2

DBMS_OUTPUT.ENABLE(buffer_size IN INTEGER DEFAULT 20000);

启用消息输出。buffer_size的NULL值表示无限的缓冲区大小。

 
3

DBMS_OUTPUT.GET_LINE(行OUT VARCHAR2,状态OUT INTEGER);

检索单行缓冲信息。

4

DBMS_OUTPUT.GET_LINES(行OUT CHARARR,numlines IN OUT INTEGER);

从缓冲区中检索一行数组。

DBMS_OUTPUT.NEW_LINE;

放置行尾标记。

6

DBMS_OUTPUT.PUT(item IN VARCHAR2);

在缓冲区中放置部分行。

7

DBMS_OUTPUT.PUT_LINE(item IN VARCHAR2);

在缓冲区中放置一行。

<span style="color:#313131">DECLARE 
   lines dbms_output<span style="color:#666600">.</span>chararr<span style="color:#666600">;</span> 
   num_lines number<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600">--</span> enable the buffer <span style="color:#000088">with</span> <span style="color:#000088">default</span> size <span style="color:#006666">20000</span> 
   dbms_output<span style="color:#666600">.</span>enable<span style="color:#666600">;</span> 
   
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Hello Reader!'</span><span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Hope you have enjoyed the tutorials!'</span><span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Have a great time exploring pl/sql!'</span><span style="color:#666600">);</span> 
  
   num_lines <span style="color:#666600">:=</span> <span style="color:#006666">3</span><span style="color:#666600">;</span> 
  
   dbms_output<span style="color:#666600">.</span>get_lines<span style="color:#666600">(</span>lines<span style="color:#666600">,</span> num_lines<span style="color:#666600">);</span> 
  
   FOR i IN <span style="color:#006666">1.</span><span style="color:#666600">.</span>num_lines LOOP 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>lines<span style="color:#666600">(</span>i<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Hello Reader! 
Hope you have enjoyed the tutorials! 
Have a great time exploring pl/sql!  

PL/SQL procedure successfully completed.
</span>

PL / SQL - 面向对象

在本章中,我们将讨论面向对象的PL / SQL。PL / SQL允许定义对象类型,这有助于在Oracle中设计面向对象的数据库。对象类型允许您创建复合类型。使用对象可以实现具有特定数据结构的现实世界对象以及操作它的方法。对象具有属性和方法。属性是对象的属性,用于存储对象的状态; 和方法用于建模其行为。

使用CREATE [OR REPLACE] TYPE语句创建对象。以下是创建一个由少数属性组成的简单地址对象的示例-

<span style="color:#313131">CREATE OR REPLACE TYPE address AS OBJECT 
<span style="color:#666600">(</span>house_no varchar2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">),</span> 
 street varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">),</span> 
 city varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">),</span> 
 state varchar2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">),</span> 
 pincode varchar2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">)</span> 
<span style="color:#666600">);</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type created. 
</span>

让我们创建一个对象客户,我们将属性方法结合在一起,以获得面向对象的感觉 -

<span style="color:#313131">CREATE OR REPLACE TYPE customer AS OBJECT 
<span style="color:#666600">(</span>code number<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">),</span> 
 name varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">),</span> 
 contact_no varchar2<span style="color:#666600">(</span><span style="color:#006666">12</span><span style="color:#666600">),</span> 
 addr address<span style="color:#666600">,</span> 
 member procedure display 
<span style="color:#666600">);</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type created.
</span>

实例化对象

定义对象类型可为对象提供蓝图。要使用此对象,需要创建此对象的实例。您可以使用实例名称和访问运算符(。)访问对象的属性和方法,如下所示 -

<span style="color:#313131">DECLARE 
   residence address<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   residence <span style="color:#666600">:=</span> address<span style="color:#666600">(</span><span style="color:#008800">'103A'</span><span style="color:#666600">,</span> <span style="color:#008800">'M.G.Road'</span><span style="color:#666600">,</span> <span style="color:#008800">'Jaipur'</span><span style="color:#666600">,</span> <span style="color:#008800">'Rajasthan'</span><span style="color:#666600">,</span><span style="color:#008800">'201301'</span><span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'House No: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>house_no<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Street: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>street<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'City: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>city<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'State: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>state<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Pincode: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>pincode<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">House No: 103A 
Street: M.G.Road 
City: Jaipur 
State: Rajasthan 
Pincode: 201301  

PL/SQL procedure successfully completed. 
</span>

成员方法

成员方法用于操纵对象的属性。在声明对象类型时提供成员方法的声明。对象体定义了成员方法的代码。使用CREATE TYPE BODY语句创建对象主体。

构造函数是返回新对象作为其值的函数。每个对象都有一个系统定义的构造函数方法。构造函数的名称与对象类型相同。例如 -

<span style="color:#313131">residence <span style="color:#666600">:=</span> address<span style="color:#666600">(</span><span style="color:#008800">'103A'</span><span style="color:#666600">,</span> <span style="color:#008800">'M.G.Road'</span><span style="color:#666600">,</span> <span style="color:#008800">'Jaipur'</span><span style="color:#666600">,</span> <span style="color:#008800">'Rajasthan'</span><span style="color:#666600">,</span><span style="color:#008800">'201301'</span><span style="color:#666600">);</span> </span>

比较方法被用于比较的对象。有两种比较对象的方法 -

地图方法

地图的方法是,它的价值取决于属性的值这样的方式实现的功能。例如,对于客户对象,如果两个客户的客户代码相同,则两个客户可以是相同的。所以这两个对象之间的关系将取决于代码的价值。

订购方式

订购方法实现了用于比较两个对象的某些内部逻辑。例如,对于矩形对象,如果矩形的两边都较大,则矩形比另一个矩形大。

使用Map方法

让我们尝试使用以下矩形对象来理解上述概念 -

<span style="color:#313131">CREATE OR REPLACE TYPE rectangle AS OBJECT 
<span style="color:#666600">(</span>length number<span style="color:#666600">,</span> 
 width number<span style="color:#666600">,</span> 
 member <span style="color:#000088">function</span> enlarge<span style="color:#666600">(</span> inc number<span style="color:#666600">)</span> <span style="color:#000088">return</span> rectangle<span style="color:#666600">,</span> 
 member procedure display<span style="color:#666600">,</span> 
 map member <span style="color:#000088">function</span> measure <span style="color:#000088">return</span> number 
<span style="color:#666600">);</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type created.
</span>

创建类型体 -

<span style="color:#313131">CREATE OR REPLACE TYPE BODY rectangle AS 
   MEMBER FUNCTION enlarge<span style="color:#666600">(</span>inc number<span style="color:#666600">)</span> <span style="color:#000088">return</span> rectangle IS 
   <span style="color:#000088">BEGIN</span> 
      <span style="color:#000088">return</span> rectangle<span style="color:#666600">(</span><span style="color:#000088">self</span><span style="color:#666600">.</span>length <span style="color:#666600">+</span> inc<span style="color:#666600">,</span> <span style="color:#000088">self</span><span style="color:#666600">.</span>width <span style="color:#666600">+</span> inc<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> enlarge<span style="color:#666600">;</span>  
   MEMBER PROCEDURE display IS 
   <span style="color:#000088">BEGIN</span>  
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Length: '</span><span style="color:#666600">||</span> length<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Width: '</span><span style="color:#666600">||</span> width<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> display<span style="color:#666600">;</span>  
   MAP MEMBER FUNCTION measure <span style="color:#000088">return</span> number IS 
   <span style="color:#000088">BEGIN</span> 
      <span style="color:#000088">return</span> <span style="color:#666600">(</span>sqrt<span style="color:#666600">(</span>length<span style="color:#666600">*</span>length <span style="color:#666600">+</span> width<span style="color:#666600">*</span>width<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> measure<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type body created.
</span>

现在使用矩形对象及其成员函数 -

<span style="color:#313131">DECLARE 
   r1 rectangle<span style="color:#666600">;</span> 
   r2 rectangle<span style="color:#666600">;</span> 
   r3 rectangle<span style="color:#666600">;</span> 
   inc_factor number <span style="color:#666600">:=</span> <span style="color:#006666">5</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   r1 <span style="color:#666600">:=</span> rectangle<span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">,</span> <span style="color:#006666">4</span><span style="color:#666600">);</span> 
   r2 <span style="color:#666600">:=</span> rectangle<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span> <span style="color:#006666">7</span><span style="color:#666600">);</span> 
   r3 <span style="color:#666600">:=</span> r1<span style="color:#666600">.</span>enlarge<span style="color:#666600">(</span>inc_factor<span style="color:#666600">);</span> 
   r3<span style="color:#666600">.</span>display<span style="color:#666600">;</span>  
   IF <span style="color:#666600">(</span>r1 <span style="color:#666600">></span> r2<span style="color:#666600">)</span> THEN <span style="color:#666600">--</span> calling measure <span style="color:#000088">function</span> 
      r1<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   ELSE 
      r2<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Length: 8 
Width: 9 
Length: 5 
Width: 7  

PL/SQL procedure successfully completed. 
</span>

使用Order方法

现在,使用订购方法可以实现相同的效果。让我们使用订单方法重新创建矩形对象 -

<span style="color:#313131">CREATE OR REPLACE TYPE rectangle AS OBJECT 
<span style="color:#666600">(</span>length number<span style="color:#666600">,</span> 
 width number<span style="color:#666600">,</span> 
 member procedure display<span style="color:#666600">,</span> 
 order member <span style="color:#000088">function</span> measure<span style="color:#666600">(</span>r rectangle<span style="color:#666600">)</span> <span style="color:#000088">return</span> number 
<span style="color:#666600">);</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type created.
</span>

创建类型体 -

<span style="color:#313131">CREATE OR REPLACE TYPE BODY rectangle AS 
   MEMBER PROCEDURE display IS 
   <span style="color:#000088">BEGIN</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Length: '</span><span style="color:#666600">||</span> length<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Width: '</span><span style="color:#666600">||</span> width<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> display<span style="color:#666600">;</span>  
   ORDER MEMBER FUNCTION measure<span style="color:#666600">(</span>r rectangle<span style="color:#666600">)</span> <span style="color:#000088">return</span> number IS 
   <span style="color:#000088">BEGIN</span> 
      IF<span style="color:#666600">(</span>sqrt<span style="color:#666600">(</span><span style="color:#000088">self</span><span style="color:#666600">.</span>length<span style="color:#666600">*</span><span style="color:#000088">self</span><span style="color:#666600">.</span>length <span style="color:#666600">+</span> <span style="color:#000088">self</span><span style="color:#666600">.</span>width<span style="color:#666600">*</span><span style="color:#000088">self</span><span style="color:#666600">.</span>width<span style="color:#666600">)></span> 
         sqrt<span style="color:#666600">(</span>r<span style="color:#666600">.</span>length<span style="color:#666600">*</span>r<span style="color:#666600">.</span>length <span style="color:#666600">+</span> r<span style="color:#666600">.</span>width<span style="color:#666600">*</span>r<span style="color:#666600">.</span>width<span style="color:#666600">))</span> <span style="color:#000088">then</span> 
         <span style="color:#000088">return</span><span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
      ELSE 
         <span style="color:#000088">return</span><span style="color:#666600">(-</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
      <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> measure<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type body created.
</span>

使用矩形对象及其成员函数 -

<span style="color:#313131">DECLARE 
   r1 rectangle<span style="color:#666600">;</span> 
   r2 rectangle<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   r1 <span style="color:#666600">:=</span> rectangle<span style="color:#666600">(</span><span style="color:#006666">23</span><span style="color:#666600">,</span> <span style="color:#006666">44</span><span style="color:#666600">);</span> 
   r2 <span style="color:#666600">:=</span> rectangle<span style="color:#666600">(</span><span style="color:#006666">15</span><span style="color:#666600">,</span> <span style="color:#006666">17</span><span style="color:#666600">);</span> 
   r1<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   r2<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   IF <span style="color:#666600">(</span>r1 <span style="color:#666600">></span> r2<span style="color:#666600">)</span> THEN <span style="color:#666600">--</span> calling measure <span style="color:#000088">function</span> 
      r1<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   ELSE 
      r2<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131"><span style="color:#7f0055">Length</span><span style="color:#666600">:</span> <span style="color:#006666">23</span> 
<span style="color:#7f0055">Width</span><span style="color:#666600">:</span> <span style="color:#006666">44</span> 
<span style="color:#7f0055">Length</span><span style="color:#666600">:</span> <span style="color:#006666">15</span> 
<span style="color:#7f0055">Width</span><span style="color:#666600">:</span> <span style="color:#006666">17</span> 
<span style="color:#7f0055">Length</span><span style="color:#666600">:</span> <span style="color:#006666">23</span> 
<span style="color:#7f0055">Width</span><span style="color:#666600">:</span> <span style="color:#006666">44</span> 

PL<span style="color:#666600">/</span>SQL procedure successfully completed<span style="color:#666600">.</span></span>

PL / SQL对象的继承

PL / SQL允许从现有的基础对象创建对象。要实现继承,应将基础对象声明为NOT FINAL。默认值为FINAL

以下程序说明了PL / SQL对象中的继承。让我们创建另一个名为TableTop的对象,它继承自Rectangle对象。为此,我们需要创建基本矩形对象 -

<span style="color:#313131">CREATE OR REPLACE TYPE rectangle AS OBJECT 
<span style="color:#666600">(</span>length number<span style="color:#666600">,</span> 
 width number<span style="color:#666600">,</span> 
 member <span style="color:#000088">function</span> enlarge<span style="color:#666600">(</span> inc number<span style="color:#666600">)</span> <span style="color:#000088">return</span> rectangle<span style="color:#666600">,</span> 
 NOT FINAL member procedure display<span style="color:#666600">)</span> NOT FINAL 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type created.
</span>

创建基本类型体 -

<span style="color:#313131">CREATE OR REPLACE TYPE BODY rectangle AS 
   MEMBER FUNCTION enlarge<span style="color:#666600">(</span>inc number<span style="color:#666600">)</span> <span style="color:#000088">return</span> rectangle IS 
   <span style="color:#000088">BEGIN</span> 
      <span style="color:#000088">return</span> rectangle<span style="color:#666600">(</span><span style="color:#000088">self</span><span style="color:#666600">.</span>length <span style="color:#666600">+</span> inc<span style="color:#666600">,</span> <span style="color:#000088">self</span><span style="color:#666600">.</span>width <span style="color:#666600">+</span> inc<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> enlarge<span style="color:#666600">;</span>  
   MEMBER PROCEDURE display IS 
   <span style="color:#000088">BEGIN</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Length: '</span><span style="color:#666600">||</span> length<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Width: '</span><span style="color:#666600">||</span> width<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> display<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type body created.
</span>

创建子对象桌面 -

<span style="color:#313131">CREATE OR REPLACE TYPE tabletop UNDER rectangle 
<span style="color:#666600">(</span>   
   material varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">),</span> 
   OVERRIDING member procedure display 
<span style="color:#666600">)</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type created.
</span>

为子对象桌面创建类型主体

<span style="color:#313131">CREATE OR REPLACE TYPE BODY tabletop AS 
OVERRIDING MEMBER PROCEDURE display IS 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Length: '</span><span style="color:#666600">||</span> length<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Width: '</span><span style="color:#666600">||</span> width<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Material: '</span><span style="color:#666600">||</span> material<span style="color:#666600">);</span> 
<span style="color:#000088">END</span> display<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type body created.
</span>

使用桌面对象及其成员函数 -

<span style="color:#313131">DECLARE 
   t1 tabletop<span style="color:#666600">;</span> 
   t2 tabletop<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   t1<span style="color:#666600">:=</span> tabletop<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">,</span> <span style="color:#006666">10</span><span style="color:#666600">,</span> <span style="color:#008800">'Wood'</span><span style="color:#666600">);</span> 
   t2 <span style="color:#666600">:=</span> tabletop<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">,</span> <span style="color:#006666">30</span><span style="color:#666600">,</span> <span style="color:#008800">'Steel'</span><span style="color:#666600">);</span> 
   t1<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   t2<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span>
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Length: 20 
Width: 10 
Material: Wood 
Length: 50 
Width: 30 
Material: Steel  

PL/SQL procedure successfully completed. 
</span>

PL / SQL中的抽象对象

不实例化子句允许你声明一个抽象的对象。您不能使用抽象对象; 您必须创建此类对象的子类型或子类型才能使用其功能。

例如,

<span style="color:#313131">CREATE OR REPLACE TYPE rectangle AS OBJECT 
<span style="color:#666600">(</span>length number<span style="color:#666600">,</span> 
 width number<span style="color:#666600">,</span> 
 NOT INSTANTIABLE NOT FINAL MEMBER PROCEDURE display<span style="color:#666600">)</span>  
 NOT INSTANTIABLE NOT FINAL 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type created.
</span>

 

             

每个PL / SQL语句都以分号(;)结尾。PL / SQL块可以使用BEGINEND嵌套在其他PL / SQL块中。以下是PL / SQL块的基本结构 -

<span style="color:#313131">DECLARE 
   <declarations section> 
BEGIN 
   <executable command(s)>
EXCEPTION 
   <exception handling> 
END;
</span>

'Hello World'示例

<span style="color:#313131">DECLARE 
   message  varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">):=</span> <span style="color:#008800">'Hello, World!'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>message<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

结束; line表示PL / SQL块的结尾。要从SQL命令行运行代码,您可能需要在代码的最后一行之后的第一个空白行的开头键入/。当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Hello World  

PL/SQL procedure successfully completed.
</span>

PL / SQL标识符

PL / SQL标识符是常量,变量,异常,过程,游标和保留字。标识符由一个字母组成,可选地后跟更多的字母,数字,美元符号,下划线和数字符号,不得超过30个字符。

默认情况下,标识符不区分大小写。因此,您可以使用整数INTEGER来表示数值。您不能使用保留关键字作为标识符。

PL / SQL分隔符

分隔符是具有特殊含义的符号。以下是PL / SQL中的分隔符列表 -

分隔符 描述
+, - ,*,/ 加法,减法/否定,乘法,除法
属性指标
字符串分隔符
组件选择器
(,) 表达式或列表分隔符
主变量指标
项目分隔符
带引号的标识符分隔符
= 关系运算符
@ 远程访问指示器
; 声明终止符
:= 分配操作员
=> 协会运营商
|| 连接运算符
** 指数运算符
<<,>> 标签分隔符(开始和结束)
/ *,* / 多行注释分隔符(开头和结尾)
- 单行评论指标
.. 范围运算符
<,>,<=,> = 关系运算符
<>,'=,〜=,^ = 不等版本的NOT EQUAL

PL / SQL评论

程序注释是可以包含在您编写的PL / SQL代码中的解释性语句,可以帮助任何人阅读其源代码。所有编程语言都允许某种形式的注释。

PL / SQL支持单行和多行注释。PL / SQL编译器会忽略任何注释中可用的所有字符。PL / SQL单行注释以分隔符开头 - (双连字符),多行注释由/ *和* /括起。

<span style="color:#313131">DECLARE 
   <span style="color:#666600">--</span> variable declaration 
   message  varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">):=</span> <span style="color:#008800">'Hello, World!'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#880000">/* 
   *  PL/SQL executable statement(s) 
   */</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>message<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131"><span style="color:#7f0055">Hello</span> <span style="color:#7f0055">World</span>

PL<span style="color:#666600">/</span>SQL procedure successfully completed<span style="color:#666600">.</span></span>

PL / SQL程序单元

PL / SQL单元是以下任何一种 -

  • PL / SQL块
  • 功能
  • 包体
  • 程序
  • 触发
  • 类型
  • 输入正文

这些单元中的每一个都将在以下章节中讨论。

PL / SQL - 数据类型

在本章中,我们将讨论PL / SQL中的数据类型。PL / SQL变量,常量和参数必须具有有效的数据类型,该类型指定存储格式,约束和有效的值范围。我们将在本章重点介绍SCALARLOB数据类型。其他两种数据类型将在其他章节中介绍。

S.No 类别和描述
1

纯量

单个值,没有内部组件,例如NUMBER,DATEBOOLEAN

2

大对象(LOB)

指向与其他数据项分开存储的大对象的指针,例如文本,图形图像,视频剪辑和声音波形。

3

综合

具有可单独访问的内部组件的数据项。例如,集合和记录。

4

参考

指向其他数据项的指针。

PL / SQL标量数据类型和子类型

PL / SQL标量数据类型和子类型属于以下类别 -

S.No 日期类型和描述
1

数字

执行算术运算的数值。

2

字符

表示单个字符或字符串的字母数字值。

3

布尔

执行逻辑操作的逻辑值。

4

约会时间

日期和时间。

PL / SQL提供了数据类型的子类型。例如,数据类型NUMBER具有名为INTEGER的子类型。您可以使用PL / SQL程序中的子类型使数据类型与其他程序中的数据类型兼容,同时将PL / SQL代码嵌入到另一个程序(如Java程序)中。

PL / SQL数字数据类型和子类型

下表列出了PL / SQL预定义数值数据类型及其子类型 -

S.No 数据类型和描述
1

PLS_INTEGER

有符号整数,范围为-2,147,483,648到2,147,483,647,以32位表示

2

BINARY_INTEGER

有符号整数,范围为-2,147,483,648到2,147,483,647,以32位表示

3

BINARY_FLOAT

单精度IEEE 754格式浮点数

4

BINARY_DOUBLE

双精度IEEE 754格式浮点数

NUMBER(预定,比例)

定点或浮点数,绝对值范围为1E-130至(但不包括)1.0E126。NUMBER变量也可以表示0

6

DEC(prec,scale)

ANSI特定定点类型,最大精度为38位十进制数

7

DECIMAL(prec,scale)

IBM特定定点类型,最大精度为38位十进制数

8

NUMERIC(pre,secale)

浮点类型,最大精度为38位十进制数

9

双精度

ANSI特定浮点类型,最大精度为126个二进制数字(约38个十进制数字)

10

浮动

ANSI和IBM特定的浮点类型,最大精度为126个二进制数字(约38个十进制数字)

11

INT

ANSI特定整数类型,最大精度为38位十进制数

12

整数

ANSI和IBM特定的整数类型,最大精度为38位十进制数

13

SMALLINT

ANSI和IBM特定的整数类型,最大精度为38位十进制数

14

真实

浮点类型,最大精度为63位二进制数字(大约18位十进制数字)

以下是有效的声明 -

<span style="color:#313131">DECLARE 
   num1 INTEGER<span style="color:#666600">;</span> 
   num2 REAL<span style="color:#666600">;</span> 
   num3 DOUBLE PRECISION<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#000088">null</span><span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

编译并执行上述代码时,会产生以下结果 -

<span style="color:#313131">PL<span style="color:#666600">/</span>SQL procedure successfully completed </span>

PL / SQL字符数据类型和子类型

以下是PL / SQL预定义字符数据类型及其子类型的详细信息 -

S.No 数据类型和描述
1

CHAR

固定长度的字符串,最大大小为32,767字节

2

VARCHAR2

可变长度字符串,最大大小为32,767字节

3

生的

可变长度二进制或字节字符串,最大大小为32,767字节,不由PL / SQL解释

4

NCHAR

固定长度的国家字符串,最大大小为32,767字节

NVARCHAR2

可变长度的国家字符串,最大大小为32,767字节

6

可变长度字符串,最大大小为32,760字节

7

LONG RAW

可变长度二进制或字节字符串,最大大小为32,760字节,不由PL / SQL解释

8

ROWID

物理行标识符,普通表中行的地址

9

UROWID

通用行标识符(物理,逻辑或外部行标识符)

PL / SQL布尔数据类型

BOOLEAN了在逻辑操作中使用的数据类型存储的逻辑值。逻辑值是布尔值TRUEFALSE以及值NULL

但是,SQL没有与BOOLEAN等效的数据类型。因此,布尔值不能用于 -

  • SQL语句
  • 内置SQL函数(如TO_CHAR
  • 从SQL语句调用的PL / SQL函数

PL / SQL日期时间和间隔类型

DATE数据类型用于存储固定长度日期时间,其中包括从午夜天的以秒计的时间。有效日期为公元前4712年1月1日至公元9999年12月31日。

默认日期格式由Oracle初始化参数NLS_DATE_FORMAT设置。例如,默认值可能是“DD-MON-YY”,其中包括月份日期的两位数字,月份名称的缩写以及年份的最后两位数字。例如,01-OCT-12。

每个日期包括世纪,年,月,日,小时,分钟和秒。下表显示了每个字段的有效值 -

字段名称 有效的日期时间值 有效间隔值
-4712至9999(不包括0年) 任何非零整数
01至12 0到11
01到31(根据区域设置的日历规则,受MONTH和YEAR的值限制) 任何非零整数
小时 00至23 0到23
分钟 00至59 0到59
第二 00至59.9(n),其中9(n)是时间分数秒的精度 0到59.9(n),其中9(n)是区间小数秒的精度
TIMEZONE_HOUR -12至14(范围适应夏令时变化) 不适用
TIMEZONE_MINUTE 00至59 不适用
TIMEZONE_REGION 在动态性能视图中找到V $ TIMEZONE_NAMES 不适用
TIMEZONE_ABBR 在动态性能视图中找到V $ TIMEZONE_NAMES 不适用

PL / SQL大对象(LOB)数据类型

大对象(LOB)数据类型指的是大数据项,例如文本,图形图像,视频剪辑和声音波形。LOB数据类型允许对此数据进行高效,随机,分段访问。以下是预定义的PL / SQL LOB数据类型 -

数据类型 描述 尺寸
BFILE 用于在数据库外部的操作系统文件中存储大型二进制对象。 取决于系统。不能超过4千兆字节(GB)。
BLOB 用于在数据库中存储大型二进制对象。 8到128太字节(TB)
CLOB 用于在数据库中存储大块字符数据。 8到128 TB
NCLOB 用于在数据库中存储大块NCHAR数据。 8到128 TB

PL / SQL用户定义的子类型

子类型是另一种数据类型的子集,称为其基本类型。子类型与其基本类型具有相同的有效操作,但只有其有效值的子集。

PL / SQL在包STANDARD中预定义了几个子类型。例如,PL / SQL预定义子类型CHARACTERINTEGER如下 -

<span style="color:#313131">SUBTYPE CHARACTER IS CHAR; 
SUBTYPE INTEGER IS NUMBER(38,0);
</span>

您可以定义和使用自己的子类型。以下程序说明了如何定义和使用用户定义的子类型 -

<span style="color:#313131">DECLARE 
   SUBTYPE name IS <span style="color:#000088">char</span><span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">);</span> 
   SUBTYPE message IS varchar2<span style="color:#666600">(</span><span style="color:#006666">100</span><span style="color:#666600">);</span> 
   salutation name<span style="color:#666600">;</span> 
   greetings message<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   salutation <span style="color:#666600">:=</span> <span style="color:#008800">'Reader '</span><span style="color:#666600">;</span> 
   greetings <span style="color:#666600">:=</span> <span style="color:#008800">'Welcome to the World of PL/SQL'</span><span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Hello '</span> <span style="color:#666600">||</span> salutation <span style="color:#666600">||</span> greetings<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Hello Reader Welcome to the World of PL/SQL 
 
PL/SQL procedure successfully completed. 
</span>

PL / SQL中的NULL

PL / SQL NULL值表示缺失未知数据,它们不是整数,字符或任何其他特定数据类型。请注意,NULL与空数据字符串或空字符值'\ 0'不同。可以指定null,但不能将其等同于任何内容,包括其自身。

PL / SQL - 变量

在本章中,我们将讨论Pl / SQL中的变量。变量只不过是我们的程序可以操作的存储区域的名称。PL / SQL中的每个变量都有一个特定的数据类型,它决定了变量内存的大小和布局; 可存储在该内存中的值范围以及可应用于该变量的操作集。

PL / SQL变量的名称由一个字母组成,可选地后跟更多的字母,数字,美元符号,下划线和数字符号,不应超过30个字符。默认情况下,变量名称不区分大小写。您不能将保留的PL / SQL关键字用作变量名。

PL / SQL编程语言允许定义各种类型的变量,例如日期时间数据类型,记录,集合等,我们将在后续章节中介绍。在本章中,我们只研究基本变量类型。

PL / SQL中的变量声明

PL / SQL变量必须在声明部分或包中声明为全局变量。声明变量时,PL / SQL为变量的值分配内存,存储位置由变量名称标识。

声明变量的语法是 -

<span style="color:#313131">variable_name [CONSTANT] datatype [NOT NULL] [:= | DEFAULT initial_value] 
</span>

其中,variable_name是PL / SQL中的有效标识符,数据类型必须是有效的PL / SQL数据类型或我们已在上一章中讨论过的任何用户定义的数据类型。一些有效的变量声明及其定义如下所示 -

<span style="color:#313131">sales number(10, 2); 
pi CONSTANT double precision := 3.1415; 
name varchar2(25); 
address varchar2(100);
</span>

当您使用数据类型提供大小,比例或精度限制时,它称为约束声明。约束声明比无约束声明需要更少的内存。例如 -

<span style="color:#313131">sales number(10, 2); 
name varchar2(25); 
address varchar2(100); 
</span>

在PL / SQL中初始化变量

每当您声明一个变量时,PL / SQL都会为其指定一个默认值NULL。如果要使用除NULL值以外的值初始化变量,则可以在声明期间使用以下任一方法执行此操作 -

  • DEFAULT关键字

  • 赋值运算符

例如 -

<span style="color:#313131">counter binary_integer := 0; 
greetings varchar2(20) DEFAULT 'Have a Good Day';
</span>

您还可以使用NOT NULL约束指定变量不应具有NULL值。如果使用NOT NULL约束,则必须为该变量显式指定初始值。

如果正确初始化变量是一个很好的编程习惯,否则程序会产生意想不到的结果。尝试使用以下示例,该示例使用各种类型的变量 -

<span style="color:#313131">DECLARE 
   a integer <span style="color:#666600">:=</span> <span style="color:#006666">10</span><span style="color:#666600">;</span> 
   b integer <span style="color:#666600">:=</span> <span style="color:#006666">20</span><span style="color:#666600">;</span> 
   c integer<span style="color:#666600">;</span> 
   f real<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   c <span style="color:#666600">:=</span> a <span style="color:#666600">+</span> b<span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Value of c: '</span> <span style="color:#666600">||</span> c<span style="color:#666600">);</span> 
   f <span style="color:#666600">:=</span> <span style="color:#006666">70.0</span><span style="color:#666600">/</span><span style="color:#006666">3.0</span><span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Value of f: '</span> <span style="color:#666600">||</span> f<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

执行上述代码时,会产生以下结果 -

<span style="color:#313131">Value of c: 30 
Value of f: 23.333333333333333333  

PL/SQL procedure successfully completed. 
</span>

PL / SQL中的变量范围

PL / SQL允许嵌套块,即每个程序块可以包含另一个内部块。如果在内部块中声明变量,则外部块无法访问它。但是,如果声明了一个变量并且外部块可以访问它,那么所有嵌套的内部块也可以访问它。变量范围有两种类型 -

  • 局部变量 - 在内部块中声明且外部块无法访问的变量。

  • 全局变量 - 在最外面的块或包中声明的变量。

以下示例以简单形式显示了LocalGlobal变量的用法-

<span style="color:#313131">DECLARE 
   <span style="color:#666600">--</span> <span style="color:#7f0055">Global</span> variables  
   num1 number <span style="color:#666600">:=</span> <span style="color:#006666">95</span><span style="color:#666600">;</span>  
   num2 number <span style="color:#666600">:=</span> <span style="color:#006666">85</span><span style="color:#666600">;</span>  
<span style="color:#000088">BEGIN</span>  
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Outer Variable num1: '</span> <span style="color:#666600">||</span> num1<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Outer Variable num2: '</span> <span style="color:#666600">||</span> num2<span style="color:#666600">);</span> 
   DECLARE  
      <span style="color:#666600">--</span> <span style="color:#7f0055">Local</span> variables 
      num1 number <span style="color:#666600">:=</span> <span style="color:#006666">195</span><span style="color:#666600">;</span>  
      num2 number <span style="color:#666600">:=</span> <span style="color:#006666">185</span><span style="color:#666600">;</span>  
   <span style="color:#000088">BEGIN</span>  
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Inner Variable num1: '</span> <span style="color:#666600">||</span> num1<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Inner Variable num2: '</span> <span style="color:#666600">||</span> num2<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span><span style="color:#666600">;</span>  
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

执行上述代码时,会产生以下结果 -

<span style="color:#313131">Outer Variable num1: 95 
Outer Variable num2: 85 
Inner Variable num1: 195 
Inner Variable num2: 185  

PL/SQL procedure successfully completed. 
</span>

将SQL查询结果分配给PL / SQL变量

您可以使用SQL 的SELECT INTO语句为PL / SQL变量赋值。对于SELECT列表中的每个项目,INTO列表中必须有对应的类型兼容变量。以下示例说明了该概念。让我们创建一个名为CUSTOMERS的表 -

对于SQL语句,请参阅SQL教程

<span style="color:#313131">CREATE TABLE CUSTOMERS<span style="color:#666600">(</span> 
   ID   INT NOT NULL<span style="color:#666600">,</span> 
   NAME VARCHAR <span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">)</span> NOT NULL<span style="color:#666600">,</span> 
   AGE INT NOT NULL<span style="color:#666600">,</span> 
   ADDRESS CHAR <span style="color:#666600">(</span><span style="color:#006666">25</span><span style="color:#666600">),</span> 
   SALARY   DECIMAL <span style="color:#666600">(</span><span style="color:#006666">18</span><span style="color:#666600">,</span> <span style="color:#006666">2</span><span style="color:#666600">),</span>        
   PRIMARY KEY <span style="color:#666600">(</span>ID<span style="color:#666600">)</span> 
<span style="color:#666600">);</span>  

<span style="color:#7f0055">Table</span> <span style="color:#7f0055">Created</span>  </span>

现在让我们在表格中插入一些值 -

<span style="color:#313131">INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">,</span> <span style="color:#008800">'Ramesh'</span><span style="color:#666600">,</span> <span style="color:#006666">32</span><span style="color:#666600">,</span> <span style="color:#008800">'Ahmedabad'</span><span style="color:#666600">,</span> <span style="color:#006666">2000.00</span> <span style="color:#666600">);</span>  

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">,</span> <span style="color:#008800">'Khilan'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Delhi'</span><span style="color:#666600">,</span> <span style="color:#006666">1500.00</span> <span style="color:#666600">);</span>  

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">,</span> <span style="color:#008800">'kaushik'</span><span style="color:#666600">,</span> <span style="color:#006666">23</span><span style="color:#666600">,</span> <span style="color:#008800">'Kota'</span><span style="color:#666600">,</span> <span style="color:#006666">2000.00</span> <span style="color:#666600">);</span>
  
INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">4</span><span style="color:#666600">,</span> <span style="color:#008800">'Chaitali'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Mumbai'</span><span style="color:#666600">,</span> <span style="color:#006666">6500.00</span> <span style="color:#666600">);</span> 
 
INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span> <span style="color:#008800">'Hardik'</span><span style="color:#666600">,</span> <span style="color:#006666">27</span><span style="color:#666600">,</span> <span style="color:#008800">'Bhopal'</span><span style="color:#666600">,</span> <span style="color:#006666">8500.00</span> <span style="color:#666600">);</span>  

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">6</span><span style="color:#666600">,</span> <span style="color:#008800">'Komal'</span><span style="color:#666600">,</span> <span style="color:#006666">22</span><span style="color:#666600">,</span> <span style="color:#008800">'MP'</span><span style="color:#666600">,</span> <span style="color:#006666">4500.00</span> <span style="color:#666600">);</span> </span>

以下程序使用SQL的SELECT INTO子句将上表中的值分配给PL / SQL变量-

<span style="color:#313131">DECLARE 
   c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type <span style="color:#666600">:=</span> <span style="color:#006666">1</span><span style="color:#666600">;</span> 
   c_name  customers<span style="color:#666600">.</span>name<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_sal  customers<span style="color:#666600">.</span>salary<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   SELECT name<span style="color:#666600">,</span> address<span style="color:#666600">,</span> salary INTO c_name<span style="color:#666600">,</span> c_addr<span style="color:#666600">,</span> c_sal 
   FROM customers 
   WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span>  
   dbms_output<span style="color:#666600">.</span>put_line 
   <span style="color:#666600">(</span><span style="color:#008800">'Customer '</span> <span style="color:#666600">||</span>c_name <span style="color:#666600">||</span> <span style="color:#008800">' from '</span> <span style="color:#666600">||</span> c_addr <span style="color:#666600">||</span> <span style="color:#008800">' earns '</span> <span style="color:#666600">||</span> c_sal<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

执行上述代码时,会产生以下结果 -

<span style="color:#313131">Customer Ramesh from Ahmedabad earns 2000  

PL/SQL procedure completed successfully
</span>

PL / SQL - 常量和文字

在本章中,我们将讨论PL / SQL中的常量文字。常量保存一个声明的值,在程序中不会更改。常量声明指定其名称,数据类型和值,并为其分配存储。声明也可以强加NOT NULL约束

声明一个常量

使用CONSTANT关键字声明常量。它需要初始值,不允许更改该值。例如 -

<span style="color:#313131">PI CONSTANT NUMBER <span style="color:#666600">:=</span> <span style="color:#006666">3.141592654</span><span style="color:#666600">;</span> 
DECLARE 
   <span style="color:#666600">--</span> constant declaration 
   pi constant number <span style="color:#666600">:=</span> <span style="color:#006666">3.141592654</span><span style="color:#666600">;</span> 
   <span style="color:#666600">--</span> other declarations 
   radius number<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span><span style="color:#006666">2</span><span style="color:#666600">);</span>  
   dia number<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span><span style="color:#006666">2</span><span style="color:#666600">);</span>  
   circumference number<span style="color:#666600">(</span><span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#006666">2</span><span style="color:#666600">);</span> 
   area number <span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">,</span> <span style="color:#006666">2</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span>  
   <span style="color:#666600">--</span> processing 
   radius <span style="color:#666600">:=</span> <span style="color:#006666">9.5</span><span style="color:#666600">;</span>  
   dia <span style="color:#666600">:=</span> radius <span style="color:#666600">*</span> <span style="color:#006666">2</span><span style="color:#666600">;</span>  
   circumference <span style="color:#666600">:=</span> <span style="color:#006666">2.0</span> <span style="color:#666600">*</span> pi <span style="color:#666600">*</span> radius<span style="color:#666600">;</span> 
   area <span style="color:#666600">:=</span> pi <span style="color:#666600">*</span> radius <span style="color:#666600">*</span> radius<span style="color:#666600">;</span> 
   <span style="color:#666600">--</span> output 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Radius: '</span> <span style="color:#666600">||</span> radius<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Diameter: '</span> <span style="color:#666600">||</span> dia<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Circumference: '</span> <span style="color:#666600">||</span> circumference<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Area: '</span> <span style="color:#666600">||</span> area<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Radius: 9.5 
Diameter: 19 
Circumference: 59.69 
Area: 283.53  

Pl/SQL procedure successfully completed. 
</span>

PL / SQL文字

文字是未由标识符表示的显式数字,字符,字符串或布尔值。例如,TRUE,786,NULL,'tutorialspoint'都是Boolean,number或string类型的文字。PL / SQL,文字区分大小写。PL / SQL支持以下类型的文字 -

  • 数字文字
  • 字符文字
  • 字符串文字
  • BOOLEAN文学
  • 日期和时间文字

下表提供了所有这些文字值类别的示例。

S.No 文字类型和示例
1

数字文字

050 78 -14 0 +32767

6.6667 0.0 -12.0 3.14159 +7800.00

6E5 1.0E-8 3.14159e0 -1E38 -9.5e-3

2

字符文字

'A''%''9''''''''''

3

字符串文字

'你好,世界!'

'教程点'

'19 -nov-12'

4

BOOLEAN文学

TRUE,FALSE和NULL。

日期和时间文字

日期'1978-12-25';

TIMESTAMP'2012-10-29 12:01:01';

要在字符串文字中嵌入单引号,请将两个单引号放在一起,如下面的程序所示 -

<span style="color:#313131">DECLARE 
   message  varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">):=</span> <span style="color:#008800">'That''s tutorialspoint.com!'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>message<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">That's tutorialspoint.com!  

PL/SQL procedure successfully completed.
</span>

PL / SQL - 运算符

在本章中,我们将讨论PL / SQL中的运算符。运算符是告诉编译器执行特定数学或逻辑操作的符号。PL / SQL语言内置运算符丰富,并提供以下类型的运算符 -

  • 算术运算符
  • 关系运算符
  • 比较运算符
  • 逻辑运算符
  • 字符串运算符

在这里,我们将逐一理解算术,关系,比较和逻辑运算符。字符串运算符将在后面的章节中讨论 - PL / SQL - 字符串

算术运算符

下表显示了PL / SQL支持的所有算术运算符。让我们假设变量A保持10,变量B保持5,然后 -

显示示例

操作者 描述
+ 添加两个操作数 A + B将给出15
- 从第一个减去第二个操作数 A - B将给5
* 将两个操作数相乘 A * B将给出50
/ 用除分子除分子 A / B将给2
** 指数运算符,将一个操作数提升到其他的幂 A ** B将给出100000

关系运算符

关系运算符比较两个表达式或值并返回布尔结果。下表显示了PL / SQL支持的所有关系运算符。让我们假设变量A保持10,变量B保持20,然后 -

显示示例

操作者 描述
= 检查两个操作数的值是否相等,如果是,则条件变为真。 (A = B)不是真的。

!=

<>

〜=

检查两个操作数的值是否相等,如果值不相等则条件变为真。 (A!= B)是真的。
> 检查左操作数的值是否大于右操作数的值,如果是,则条件变为真。 (A> B)不是真的。
< 检查左操作数的值是否小于右操作数的值,如果是,则条件变为真。 (A <B)是真的。
> = 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件变为真。 (A> = B)不是真的。
<= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件变为真。 (A <= B)是真的

比较运算符

比较运算符用于比较一个表达式与另一个表达式。结果始终为TRUE,FALSENULL

显示示例

操作者 描述
喜欢 LIKE运算符将字符,字符串或CLOB值与模式进行比较,如果值与模式匹配则返回TRUE,否则返回FALSE。 如果'Zara Ali'喜欢'Z%A_i'返回布尔值true,而'Nuha Ali'喜欢'Z%A_i'返回布尔值false。
之间 BETWEEN运算符测试值是否在指定范围内。x BETWEEN a AND b表示x> = a且x <= b。 如果x = 10那么,5到20之间的x返回true,5到10之间的x返回true,但是11到20之间的x返回false。
IN运算符测试设置成员资格。x IN(set)表示x等于set的任何成员。 如果x ='m'那么,x in('a','b','c')返回布尔值false但x in('m','n','o')返回布尔值true。
一片空白 如果操作数为NULL,则IS NULL运算符返回BOOLEAN值TRUE,如果不为NULL,则返回FALSE。涉及NULL值的比较总是产生NULL。 如果x ='m',则'x为null'返回布尔值false。

逻辑运算符

下表显示了PL / SQL支持的逻辑运算符。所有这些运算符都处理布尔操作数并生成布尔结果。让我们假设变量A成立,变量B成立假,然后 -

显示示例

操作者 描述 例子
称为逻辑AND运算符。如果两个操作数均为真,则条件成立。 (A和B)是假的。
要么 称为逻辑OR运算符。如果两个操作数中的任何一个为真,则条件成立。 (A或B)是真的。
称为逻辑NOT运算符。用于反转其操作数的逻辑状态。如果条件为真,则Logical NOT运算符将使其为假。 不(A和B)是真的。

PL / SQL运算符优先级

运算符优先级确定表达式中的术语分组。这会影响表达式的计算方式。某些运营商的优先级高于其他运营商; 例如,乘法运算符的优先级高于加法运算符。

例如,x = 7 + 3 * 2 ; 这里,x被赋值为13,而不是20,因为operator *的优先级高于+,所以它首先乘以3 * 2然后加到7中

此处,具有最高优先级的运算符显示在表的顶部,具有最低优先级的运算符显示在底部。在表达式中,将首先评估更高优先级的运算符。

运算符的优先级如下:=,<,>,<=,> =,<>,!=,〜=,^ =,IS NULL,LIKE,BETWEEN,IN。

显示示例

操作者 手术
**
+, - 身份,否定
*,/ 乘法,除法
+, - ,|| 加法,减法,连接
对照  
逻辑否定
连词
要么 包容

PL / SQL - 条件

在本章中,我们将讨论PL / SQL中的条件。决策结构要求程序员指定一个或多个要由程序评估或测试的条件,以及在条件被确定为真时要执行的一个或多个语句,以及可选的其他语句,如果条件被确定为假。

以下是大多数编程语言中发现的典型条件(即决策)结构的一般形式 -

PL / SQL中的决策语句

PL / SQL编程语言提供以下类型的决策制定语句。单击以下链接以检查其详细信息。

S.No 声明和说明
1 IF - 那么声明

IF语句与使用关键字封闭的语句序列相关联的条件THENEND IF。如果条件为真,则执行语句,如果条件为false或NULL,则IF语句不执行任何操作。

2 IF-THEN-ELSE声明

IF语句添加关键字ELSE,后跟另一个语句序列。如果条件为false或NULL,则只执行替代语句序列。它确保执行任一语句序列。

3 IF-THEN-ELSIF声明

它允许您在几种选择之间进行选择。

4 案例陈述

与IF语句一样,CASE语句选择要执行的一个语句序列。

但是,要选择序列,CASE语句使用选择器而不是多个布尔表达式。选择器是一个表达式,其值用于选择多个备选项之一。

搜索CASE声明

搜索到的CASE语句没有选择器,它的WHEN子句包含产生布尔值的搜索条件。

6 嵌套的IF-THEN-ELSE

您可以在另一个IF-THENIF-THEN-ELSIF语句中使用一个IF-THENIF-THEN-ELSIF语句。

PL / SQL - 循环

在本章中,我们将讨论PL / SQL中的循环。可能存在需要多次执行代码块的情况。通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。

编程语言提供各种控制结构,允许更复杂的执行路径。

循环语句允许我们多次执行语句或语句组,以下是大多数编程语言中循环语句的一般形式 -

循环架构

PL / SQL提供以下类型的循环来处理循环要求。单击以下链接以检查其详细信息。

S.No 循环类型和描述
1 PL / SQL基本循环

在此循环结构中,语句序列包含在LOOP和END LOOP语句之间。在每次迭代时,执行语句序列,然后控制在循环的顶部重新开始。

2 PL / SQL WHILE循环

在给定条件为真时重复语句或语句组。它在执行循环体之前测试条件。

3 PL / SQL FOR LOOP

多次执行一系列语句,并缩写管理循环变量的代码。

4 PL / SQL中的嵌套循环

您可以在任何其他基本循环中使用一个或多个循环,或者用于循环。

标记PL / SQL循环

可以标记PL / SQL循环。标签应该用双尖括号(<<和>>)括起来,并出现在LOOP语句的开头。标签名称也可以出现在LOOP语句的末尾。您可以使用EXIT语句中的标签退出循环。

以下计划说明了这一概念 -

<span style="color:#313131">DECLARE 
   i number<span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
   j number<span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600"><<</span> outer_loop <span style="color:#666600">>></span> 
   FOR i IN <span style="color:#006666">1.</span><span style="color:#666600">.</span><span style="color:#006666">3</span> LOOP 
      <span style="color:#666600"><<</span> inner_loop <span style="color:#666600">>></span> 
      FOR j IN <span style="color:#006666">1.</span><span style="color:#666600">.</span><span style="color:#006666">3</span> LOOP 
         dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'i is: '</span><span style="color:#666600">||</span> i <span style="color:#666600">||</span> <span style="color:#008800">' and j is: '</span> <span style="color:#666600">||</span> j<span style="color:#666600">);</span> 
      <span style="color:#000088">END</span> loop inner_loop<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> loop outer_loop<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">i is: 1 and j is: 1 
i is: 1 and j is: 2 
i is: 1 and j is: 3 
i is: 2 and j is: 1 
i is: 2 and j is: 2 
i is: 2 and j is: 3 
i is: 3 and j is: 1 
i is: 3 and j is: 2 
i is: 3 and j is: 3  

PL/SQL procedure successfully completed. 
</span>

循环控制语句

循环控制语句将执行从其正常序列更改。当执行离开作用域时,将销毁在该作用域中创建的所有自动对象。

PL / SQL支持以下控制语句。标记循环也有助于将控件置于循环之外。单击以下链接以查看其详细信息。

S.No 控制声明和描述
1 退出声明

Exit语句完成循环并且控制在END LOOP之后立即传递给语句。

2 CONTINUE声明

导致循环跳过其身体的其余部分,并在重复之前立即重新测试其状态。

3 GOTO声明

将控制转移到带标签的声明。虽然不建议在程序中使用GOTO语句。

PL / SQL - 字符串

PL / SQL中的字符串实际上是一个具有可选大小规范的字符序列。字符可以是数字,字母,空白,特殊字符或所有字符的组合。PL / SQL提供三种字符串 -

  • 固定长度的字符串 - 在这样的字符串中,程序员在声明字符串时指定长度。字符串右边用空格填充到指定的长度。

  • 可变长度字符串 - 在此类字符串中,指定字符串的最大长度最大为32,767,并且不会发生填充。

  • 字符大对象(CLOB) - 这些是可变长度的字符串,最多可达128 TB。

PL / SQL字符串可以是变量或文字。字符串文字用引号括起来。例如,

<span style="color:#313131">'This is a string literal.' Or 'hello world'
</span>

要在字符串文字中包含单引号,您需要在彼此旁边键入两个单引号。例如,

<span style="color:#313131">'this isn''t what it looks like'
</span>

声明字符串变量

Oracle数据库提供了许多字符串数据类型,例如CHAR,NCHAR,VARCHAR2,NVARCHAR2,CLOB和NCLOB。前缀为“N” 数据类型是“国家字符集”数据类型,用于存储Unicode字符数据。

如果需要声明可变长度字符串,则必须提供该字符串的最大长度。例如,VARCHAR2数据类型。以下示例说明了声明和使用一些字符串变量 -

<span style="color:#313131">DECLARE 
   name varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">);</span> 
   company varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">);</span> 
   introduction clob<span style="color:#666600">;</span> 
   choice <span style="color:#000088">char</span><span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   name <span style="color:#666600">:=</span> <span style="color:#008800">'John Smith'</span><span style="color:#666600">;</span> 
   company <span style="color:#666600">:=</span> <span style="color:#008800">'Infotech'</span><span style="color:#666600">;</span> 
   introduction <span style="color:#666600">:=</span> <span style="color:#008800">' Hello! I''m John Smith from Infotech.'</span><span style="color:#666600">;</span> 
   choice <span style="color:#666600">:=</span> <span style="color:#008800">'y'</span><span style="color:#666600">;</span> 
   IF choice <span style="color:#666600">=</span> <span style="color:#008800">'y'</span> THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>name<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>company<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>introduction<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">John Smith 
Infotech Corporation 
Hello! I'm John Smith from Infotech.  

PL/SQL procedure successfully completed
</span>

要声明固定长度的字符串,请使用CHAR数据类型。在这里,您不必为固定长度变量指定最大长度。如果不使用长度约束,Oracle数据库将自动使用所需的最大长度。以下两个声明是相同的 -

<span style="color:#313131">red_flag CHAR(1) := 'Y'; 
 red_flag CHAR   := 'Y';
</span>

PL / SQL字符串函数和操作符

PL / SQL提供连接运算符(||)来连接两个字符串。下表提供了PL / SQL提供的字符串函数 -

S.No 功能与目的
1

ASCII(X);

返回字符x的ASCII值。

2

CHR(X);

返回ASCII值为x的字符。

3

CONCAT(x,y);

连接字符串x和y并返回附加的字符串。

4

INITCAP(X);

将x中每个单词的首字母转换为大写并返回该字符串。

INSTR(x,find_string [,start] [,occurrence]);

在x中搜索find_string并返回它出现的位置。

6

INSTRB(X);

返回另一个字符串中字符串的位置,但返回以字节为单位的值。

7

长度(X);

返回x中的字符数。

8

LENGTHB(X);

返回单字节字符集的字符串长度(以字节为单位)。

9

LOWER(X);

将x中的字母转换为小写并返回该字符串。

10

LPAD(x,width [,pad_string]);

填充x左侧有空格,以使字符串的总长度达到宽度字符。

11

LTRIM(x [,trim_string]);

修剪x左侧的字符。

12

NANVL(x,值);

如果x与NaN特殊值(不是数字)匹配,则返回值,否则返回x

13

NLS_INITCAP(X);

与INITCAP函数相同,但它可以使用NLSSORT指定的其他排序方法。

14

NLS_LOWER(x);

与LOWER函数相同,只是它可以使用NLSSORT指定的其他排序方法。

15

NLS_UPPER(X);

与UPPER函数相同,但它可以使用NLSSORT指定的其他排序方法。

16

NLSSORT(X);

更改排序字符的方法。必须在任何NLS功能之前指定; 否则,将使用默认排序。

17

NVL(x,值);

如果x为null,则返回值; 否则,返回x。

18

NVL2(x,value1,value2);

如果x不为null,则返回value1; 如果x为null,则返回value2。

19

REPLACE(x,search_string,replace_string);

x中搜索search_string并将其替换为replace_string。

20

RPAD(x,width [,pad_string]);

x到右边。

21

RTRIM(x [,trim_string]);

从右边修剪x

22

SOUNDEX(x);

返回包含x的语音表示的字符串。

23

SUBSTR(x,start [,length]);

返回x的子字符串,该子字符串从start指定的位置开始。可以提供子串的可选长度。

24

SUBSTRB(X);

与SUBSTR相同,除了参数以字节表示而不是单字节字符系统的字符。

25

TRIM([trim_char FROM)x);

修剪x左右两侧的字符。

26

UPPER(X);

将x中的字母转换为大写并返回该字符串。

现在让我们通过几个例子来理解这个概念 -

例1

<span style="color:#313131">DECLARE 
   greetings varchar2<span style="color:#666600">(</span><span style="color:#006666">11</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#008800">'hello world'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>UPPER<span style="color:#666600">(</span>greetings<span style="color:#666600">));</span> 
    
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>LOWER<span style="color:#666600">(</span>greetings<span style="color:#666600">));</span> 
    
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>INITCAP<span style="color:#666600">(</span>greetings<span style="color:#666600">));</span> 
    
   <span style="color:#880000">/* retrieve the first character in the string */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> SUBSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#006666">1</span><span style="color:#666600">,</span> <span style="color:#006666">1</span><span style="color:#666600">));</span> 
    
   <span style="color:#880000">/* retrieve the last character in the string */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> SUBSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#666600">-</span><span style="color:#006666">1</span><span style="color:#666600">,</span> <span style="color:#006666">1</span><span style="color:#666600">));</span> 
    
   <span style="color:#880000">/* retrieve five characters,  
      starting from the seventh position. */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> SUBSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#006666">5</span><span style="color:#666600">));</span> 
    
   <span style="color:#880000">/* retrieve the remainder of the string, 
      starting from the second position. */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> SUBSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#006666">2</span><span style="color:#666600">));</span> 
     
   <span style="color:#880000">/* find the location of the first "e" */</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span> INSTR <span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#008800">'e'</span><span style="color:#666600">));</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">HELLO WORLD 
hello world 
Hello World 
h 
d 
World 
ello World 
2  

PL/SQL procedure successfully completed.
</span>

例2

<span style="color:#313131">DECLARE 
   greetings varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#008800">'......Hello World.....'</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>RTRIM<span style="color:#666600">(</span>greetings<span style="color:#666600">,</span><span style="color:#008800">'.'</span><span style="color:#666600">));</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>LTRIM<span style="color:#666600">(</span>greetings<span style="color:#666600">,</span> <span style="color:#008800">'.'</span><span style="color:#666600">));</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>TRIM<span style="color:#666600">(</span> <span style="color:#008800">'.'</span> <span style="color:#000088">from</span> greetings<span style="color:#666600">));</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">......Hello World  
Hello World..... 
Hello World  

PL/SQL procedure successfully completed. 
</span>

PL / SQL - 数组

在本章中,我们将讨论PL / SQL中的数组。PL / SQL编程语言提供了一个名为VARRAY的数据结构,它可以存储相同类型元素的固定大小顺序集合。varray用于存储有序的数据集合,但通常最好将数组视为相同类型的变量集合。

所有varrays都包含连续的内存位置。最低地址对应于第一个元素,最高地址对应于最后一个元素。

PL / SQL中的变量

数组是集合类型数据的一部分,它代表可变大小的数组。我们将在后面的“PL / SQL集合”一章中研究其他集合类型。

varray中的每个元素都有一个与之关联的索引。它还具有可以动态更改的最大大小。

创建Varray类型

使用CREATE TYPE语句创建varray类型。您必须指定存储在varray中的最大大小和元素类型。

在架构级别创建VARRAY类型的基本语法是 -

<span style="color:#313131">CREATE OR REPLACE TYPE varray_type_name IS VARRAY(n) of <element_type>
</span>

哪里,

  • varray_type_name是一个有效的属性名称,
  • n是varray中元素的数量(最大值),
  • element_type是数组元素的数据类型。

可以使用ALTER TYPE语句更改varray的最大大小。

例如,

<span style="color:#313131">CREATE <span style="color:#7f0055">Or</span> REPLACE TYPE namearray AS VARRAY<span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">)</span> OF VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">);</span> 
<span style="color:#666600">/</span> 

<span style="color:#7f0055">Type</span> created<span style="color:#666600">.</span></span>

在PL / SQL块中创建VARRAY类型的基本语法是 -

 

<span style="color:#313131">TYPE varray_type_name IS VARRAY(n) of <element_type>
</span>

例如 -

<span style="color:#313131">TYPE namearray IS VARRAY<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">)</span> OF VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">);</span> 
<span style="color:#7f0055">Type</span> grades IS VARRAY<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">)</span> OF INTEGER<span style="color:#666600">;</span></span>

现在让我们通过几个例子来理解这个概念 -

例1

以下程序说明了varrays的使用 -

<span style="color:#313131">DECLARE 
   type namesarray IS VARRAY<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">)</span> OF VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">);</span> 
   type grades IS VARRAY<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">)</span> OF INTEGER<span style="color:#666600">;</span> 
   names namesarray<span style="color:#666600">;</span> 
   marks grades<span style="color:#666600">;</span> 
   total integer<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   names <span style="color:#666600">:=</span> namesarray<span style="color:#666600">(</span><span style="color:#008800">'Kavita'</span><span style="color:#666600">,</span> <span style="color:#008800">'Pritam'</span><span style="color:#666600">,</span> <span style="color:#008800">'Ayan'</span><span style="color:#666600">,</span> <span style="color:#008800">'Rishav'</span><span style="color:#666600">,</span> <span style="color:#008800">'Aziz'</span><span style="color:#666600">);</span> 
   marks<span style="color:#666600">:=</span> grades<span style="color:#666600">(</span><span style="color:#006666">98</span><span style="color:#666600">,</span> <span style="color:#006666">97</span><span style="color:#666600">,</span> <span style="color:#006666">78</span><span style="color:#666600">,</span> <span style="color:#006666">87</span><span style="color:#666600">,</span> <span style="color:#006666">92</span><span style="color:#666600">);</span> 
   total <span style="color:#666600">:=</span> names<span style="color:#666600">.</span>count<span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Total '</span><span style="color:#666600">||</span> total <span style="color:#666600">||</span> <span style="color:#008800">' Students'</span><span style="color:#666600">);</span> 
   FOR i <span style="color:#000088">in</span> <span style="color:#006666">1</span> <span style="color:#666600">..</span> total LOOP 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Student: '</span> <span style="color:#666600">||</span> names<span style="color:#666600">(</span>i<span style="color:#666600">)</span> <span style="color:#666600">||</span> <span style="color:#008800">' 
      Marks: '</span> <span style="color:#666600">||</span> marks<span style="color:#666600">(</span>i<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Total 5 Students 
Student: Kavita  Marks: 98 
Student: Pritam  Marks: 97 
Student: Ayan  Marks: 78 
Student: Rishav  Marks: 87 
Student: Aziz  Marks: 92 

PL/SQL procedure successfully completed. 
</span>

请注意 -

  • 在Oracle环境中,varrays的起始索引始终为1。

  • 您可以使用varray类型的构造方法初始化varray元素,该方法与varray具有相同的名称。

  • Varrays是一维数组。

  • varray在声明时自动为NULL,必须在引用其元素之前进行初始化。

例2

varray的元素也可以是任何数据库表的%ROWTYPE或任何数据库表字段的%TYPE。以下示例说明了该概念。

我们将使用存储在我们数据库中的CUSTOMERS表作为 -

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+ 
</span>

下面的示例使用了光标,您将在另一章中详细研究。

<span style="color:#313131">DECLARE 
   CURSOR c_customers <span style="color:#000088">is</span> 
   SELECT  name FROM customers<span style="color:#666600">;</span> 
   type c_list <span style="color:#000088">is</span> varray <span style="color:#666600">(</span><span style="color:#006666">6</span><span style="color:#666600">)</span> of customers<span style="color:#666600">.</span>name<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   name_list c_list <span style="color:#666600">:=</span> c_list<span style="color:#666600">();</span> 
   counter integer <span style="color:#666600">:=</span><span style="color:#006666">0</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   FOR n IN c_customers LOOP 
      counter <span style="color:#666600">:=</span> counter <span style="color:#666600">+</span> <span style="color:#006666">1</span><span style="color:#666600">;</span> 
      name_list<span style="color:#666600">.</span>extend<span style="color:#666600">;</span> 
      name_list<span style="color:#666600">(</span>counter<span style="color:#666600">)</span>  <span style="color:#666600">:=</span> n<span style="color:#666600">.</span>name<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer('</span><span style="color:#666600">||</span>counter <span style="color:#666600">||</span><span style="color:#008800">'):'</span><span style="color:#666600">||</span>name_list<span style="color:#666600">(</span>counter<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131"><span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">):</span> <span style="color:#7f0055">Ramesh</span>  
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">):</span> <span style="color:#7f0055">Khilan</span>  
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">):</span> kaushik     
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">4</span><span style="color:#666600">):</span> <span style="color:#7f0055">Chaitali</span>  
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">):</span> <span style="color:#7f0055">Hardik</span>  
<span style="color:#7f0055">Customer</span><span style="color:#666600">(</span><span style="color:#006666">6</span><span style="color:#666600">):</span> <span style="color:#7f0055">Komal</span>  

PL<span style="color:#666600">/</span>SQL procedure successfully completed<span style="color:#666600">.</span> </span>

PL / SQL - 程序

在本章中,我们将讨论PL / SQL中的过程。甲子程序是程序单元/模块,其执行特定的任务。这些子程序组合在一起形成更大的程序。这基本上被称为“模块化设计”。子程序可以由另一个子程序或程序调用,称为调用程序

可以创建子程序 -

  • 在架构级别
  • 在包内
  • 在PL / SQL块中

在模式级别,子程序是一个独立的子程序。它是使用CREATE PROCEDURE或CREATE FUNCTION语句创建的。它存储在数据库中,可以使用DROP PROCEDURE或DROP FUNCTION语句删除。

在包内创建的子程序是打包的子程序。它存储在数据库中,只有在使用DROP PACKAGE语句删除包时才能删除它。我们将在“PL / SQL - 包”一章中讨论包。

PL / SQL子程序被命名为PL / SQL块,可以使用一组参数调用它们。PL / SQL提供两种子程序 -

  • 函数 - 这些子程序返回单个值; 主要用于计算和返回一个值。

  • 程序 - 这些子程序不直接返回值; 主要用于执行动作。

本章将介绍PL / SQL过程的重要方面。我们将在下一章讨论PL / SQL函数

PL / SQL子程序的一部分

每个PL / SQL子程序都有一个名称,也可能有一个参数列表。与匿名PL / SQL块一样,命名块也将包含以下三个部分 -

S.No 零件和描述
1

声明部分

这是一个可选部分。但是,子程序的声明部分不是以DECLARE关键字开头的。它包含类型,游标,常量,变量,异常和嵌套子程序的声明。这些项目是子程序的本地项目,并在子程序完成执行时不再存在。

2

可执行部分

这是必需部分,包含执行指定操作的语句。

3

异常处理

这也是一个可选部分。它包含处理运行时错误的代码。

创建程序

使用CREATE OR REPLACE PROCEDURE语句创建过程。CREATE OR REPLACE PROCEDURE语句的简化语法如下 -

<span style="color:#313131">CREATE <span style="color:#666600">[</span>OR REPLACE<span style="color:#666600">]</span> PROCEDURE procedure_name 
<span style="color:#666600">[(</span>parameter_name <span style="color:#666600">[</span>IN <span style="color:#666600">|</span> OUT <span style="color:#666600">|</span> IN OUT<span style="color:#666600">]</span> type <span style="color:#666600">[,</span> <span style="color:#666600">...])]</span> 
<span style="color:#666600">{</span>IS <span style="color:#666600">|</span> AS<span style="color:#666600">}</span> 
<span style="color:#000088">BEGIN</span> 
  <span style="color:#666600"><</span> procedure_body <span style="color:#666600">></span> 
<span style="color:#000088">END</span> procedure_name<span style="color:#666600">;</span> </span>

哪里,

  • procedure-name指定过程的名称

  • [OR REPLACE]选项允许修改现有过程。

  • 可选参数列表包含参数的名称,模式和类型。IN表示将从外部传递的值,OUT表示将用于在过程外返回值的参数。

  • procedure-body包含可执行部分。

  • 使用AS关键字代替IS关键字来创建独立过程。

以下示例创建一个显示字符串'Hello World!'的简单过程。在执行时在屏幕上。

<span style="color:#313131">CREATE OR REPLACE PROCEDURE greetings 
AS 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Hello World!'</span><span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当使用SQL提示执行上述代码时,它将产生以下结果 -

<span style="color:#313131">Procedure created.
</span>

执行独立过程

可以通过两种方式调用独立过程 -

  • 使用EXECUTE关键字

  • 从PL / SQL块调用过程的名称

可以使用EXECUTE关键字调用上述名为'greetings'的过程-

<span style="color:#313131">EXECUTE greetings;
</span>

以上电话会显示 -

<span style="color:#313131">Hello World

PL/SQL procedure successfully completed.
</span>

也可以从另一个PL / SQL块调用该过程 -

<span style="color:#313131"><span style="color:#000088">BEGIN</span> 
   greetings<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

以上电话会显示 -

<span style="color:#313131">Hello World  

PL/SQL procedure successfully completed. 
</span>

删除独立过程

使用DROP PROCEDURE语句删除独立过程。删除程序的语法是 -

<span style="color:#313131">DROP PROCEDURE procedure-name; 
</span>

您可以使用以下声明删除问候程序 -

<span style="color:#313131">DROP PROCEDURE greetings; 
</span>

PL / SQL子程序中的参数模式

下表列出了PL / SQL子程序中的参数模式 -

S.No 参数模式和说明
1

IN参数允许您将值传递给子程序。它是一个只读参数。在子程序内部,IN参数的作用类似于常量。它无法分配值。您可以将常量,文字,初始化变量或表达式作为IN参数传递。您也可以将其初始化为默认值; 但是,在这种情况下,子程序调用中省略了它。它是参数传递的默认模式。参数通过引用传递

2

OUT

OUT参数向调用程序返回一个值。在子程序内部,OUT参数就像一个变量。您可以在分配值后更改其值并引用该值。实际参数必须是可变的,并按值传递

3

进出

一个IN OUT参数传递的初始值到一个子程序,并返回更新值给调用者。可以为其分配值,并且可以读取该值。

对应于IN OUT形式参数的实际参数必须是变量,而不是常量或表达式。必须为正式参数分配值。实际参数按值传递。

IN&OUT模式示例1

该程序找到最少两个值。这里,该过程使用IN模式获取两个数字,并使用OUT参数返回其最小值。

<span style="color:#313131">DECLARE 
   a number<span style="color:#666600">;</span> 
   b number<span style="color:#666600">;</span> 
   c number<span style="color:#666600">;</span>
PROCEDURE findMin<span style="color:#666600">(</span>x IN number<span style="color:#666600">,</span> y IN number<span style="color:#666600">,</span> z OUT number<span style="color:#666600">)</span> IS 
<span style="color:#000088">BEGIN</span> 
   IF x <span style="color:#666600"><</span> y THEN 
      z<span style="color:#666600">:=</span> x<span style="color:#666600">;</span> 
   ELSE 
      z<span style="color:#666600">:=</span> y<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span>   
<span style="color:#000088">BEGIN</span> 
   a<span style="color:#666600">:=</span> <span style="color:#006666">23</span><span style="color:#666600">;</span> 
   b<span style="color:#666600">:=</span> <span style="color:#006666">45</span><span style="color:#666600">;</span> 
   findMin<span style="color:#666600">(</span>a<span style="color:#666600">,</span> b<span style="color:#666600">,</span> c<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">' Minimum of (23, 45) : '</span> <span style="color:#666600">||</span> c<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Minimum of (23, 45) : 23  

PL/SQL procedure successfully completed. 
</span>

IN&OUT模式示例2

此过程计算传递值的平方值。此示例显示了我们如何使用相同的参数接受值,然后返回另一个结果。

<span style="color:#313131">DECLARE 
   a number<span style="color:#666600">;</span> 
PROCEDURE squareNum<span style="color:#666600">(</span>x IN OUT number<span style="color:#666600">)</span> IS 
<span style="color:#000088">BEGIN</span> 
  x <span style="color:#666600">:=</span> x <span style="color:#666600">*</span> x<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span>  
<span style="color:#000088">BEGIN</span> 
   a<span style="color:#666600">:=</span> <span style="color:#006666">23</span><span style="color:#666600">;</span> 
   squareNum<span style="color:#666600">(</span>a<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">' Square of (23): '</span> <span style="color:#666600">||</span> a<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Square of (23): 529 

PL/SQL procedure successfully completed.
</span>

传递参数的方法

实际参数可以通过三种方式传递 -

  • 位置符号
  • 命名符号
  • 混合符号

位置符号

在位置表示法中,您可以将程序称为 -

<span style="color:#313131">findMin(a, b, c, d);
</span>

在位置表示法中,第一个实际参数代替第一个形式参数; 第二个实际参数代替第二个形式参数,依此类推。因此,a代替x,b代替y,c代替zd代替m

命名表示法

在命名表示法中,实际参数使用箭头符号(=>)与形式参数相关联。程序调用将如下所示 -

<span style="color:#313131">findMin(x => a, y => b, z => c, m => d);
</span>

混合符号

在混合符号中,您可以在过程调用中混合使用两种符号; 但是,位置表示法应该在命名表示法之前。

以下电话是合法的 -

<span style="color:#313131">findMin(a, b, c, m => d);
</span>

但是,这不合法:

<span style="color:#313131">findMin(x => a, b, c, d); 
</span>

PL / SQL - 功能

在本章中,我们将讨论PL / SQL中的函数。函数与过程相同,只是它返回一个值。因此,前一章的所有讨论也适用于函数。

创建一个函数

使用CREATE FUNCTION语句创建独立函数。CREATE OR REPLACE PROCEDURE语句的简化语法如下 -

<span style="color:#313131">CREATE [OR REPLACE] FUNCTION function_name 
[(parameter_name [IN | OUT | IN OUT] type [, ...])] 
RETURN return_datatype 
{IS | AS} 
BEGIN 
   < function_body > 
END [function_name];
</span>

哪里,

  • function-name指定函数的名称

  • [OR REPLACE]选项允许修改现有功能。

  • 可选参数列表包含参数的名称,模式和类型。IN表示将从外部传递的值,OUT表示将用于在过程外返回值的参数。

  • 该函数必须包含return语句。

  • RETURN子句指定的数据类型,你打算从函数返回。

  • function-body包含可执行部分。

  • 使用AS关键字代替IS关键字来创建独立功能。

以下示例说明了如何创建和调用独立函数。此函数返回customers表中的CUSTOMERS总数。

我们将使用我们在PL / SQL变量章节中创建的CUSTOMERS表-

<span style="color:#313131">Select * from customers; 
 
+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+  
</span>
<span style="color:#313131">CREATE OR REPLACE FUNCTION totalCustomers 
RETURN number IS 
   total number<span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">0</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   SELECT count<span style="color:#666600">(*)</span> <span style="color:#000088">into</span> total 
   FROM customers<span style="color:#666600">;</span> 
    
   RETURN total<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当使用SQL提示执行上述代码时,它将产生以下结果 -

<span style="color:#313131">Function created.
</span>

调用函数

在创建函数时,您可以定义函数必须执行的操作。要使用函数,您必须调用该函数来执行定义的任务。程序调用函数时,程序控制转移到被调用函数。

被调用的函数执行定义的任务,当执行其return语句或到达最后一个结束语句时,它将程序控制返回给主程序。

要调用函数,只需要传递必需的参数和函数名称,如果函数返回值,则可以存储返回的值。以下程序从匿名块调用函数totalCustomers -

<span style="color:#313131">DECLARE 
   c number<span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   c <span style="color:#666600">:=</span> totalCustomers<span style="color:#666600">();</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Total no. of Customers: '</span> <span style="color:#666600">||</span> c<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Total no. of Customers: 6  

PL/SQL procedure successfully completed. 
</span>

以下示例演示了声明,定义和调用简单PL / SQL函数,该函数计算并返回最多两个值。

<span style="color:#313131">DECLARE 
   a number<span style="color:#666600">;</span> 
   b number<span style="color:#666600">;</span> 
   c number<span style="color:#666600">;</span> 
FUNCTION findMax<span style="color:#666600">(</span>x IN number<span style="color:#666600">,</span> y IN number<span style="color:#666600">)</span>  
RETURN number 
IS 
    z number<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   IF x <span style="color:#666600">></span> y THEN 
      z<span style="color:#666600">:=</span> x<span style="color:#666600">;</span> 
   ELSE 
      Z<span style="color:#666600">:=</span> y<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span>  
   RETURN z<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   a<span style="color:#666600">:=</span> <span style="color:#006666">23</span><span style="color:#666600">;</span> 
   b<span style="color:#666600">:=</span> <span style="color:#006666">45</span><span style="color:#666600">;</span>  
   c <span style="color:#666600">:=</span> findMax<span style="color:#666600">(</span>a<span style="color:#666600">,</span> b<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">' Maximum of (23,45): '</span> <span style="color:#666600">||</span> c<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Maximum of (23,45): 45   

PL/SQL procedure successfully completed. 
</span>

PL / SQL递归函数

我们已经看到程序或子程序可能会调用另一个子程序。当子程序调用自身时,它被称为递归调用,该过程称为递归

为了说明这个概念,让我们计算一个数的阶乘。数字n的因子定义为 -

<span style="color:#313131">n! = n*(n-1)! 
   = n*(n-1)*(n-2)! 
      ... 
   = n*(n-1)*(n-2)*(n-3)... 1 
</span>

以下程序通过递归调用自身计算给定数字的阶乘 -

<span style="color:#313131">DECLARE 
   num number<span style="color:#666600">;</span> 
   factorial number<span style="color:#666600">;</span>  
   
FUNCTION fact<span style="color:#666600">(</span>x number<span style="color:#666600">)</span> 
RETURN number  
IS 
   f number<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   IF x<span style="color:#666600">=</span><span style="color:#006666">0</span> THEN 
      f <span style="color:#666600">:=</span> <span style="color:#006666">1</span><span style="color:#666600">;</span> 
   ELSE 
      f <span style="color:#666600">:=</span> x <span style="color:#666600">*</span> fact<span style="color:#666600">(</span>x<span style="color:#666600">-</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
RETURN f<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span>  

<span style="color:#000088">BEGIN</span> 
   num<span style="color:#666600">:=</span> <span style="color:#006666">6</span><span style="color:#666600">;</span> 
   factorial <span style="color:#666600">:=</span> fact<span style="color:#666600">(</span>num<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">' Factorial '</span><span style="color:#666600">||</span> num <span style="color:#666600">||</span> <span style="color:#008800">' is '</span> <span style="color:#666600">||</span> factorial<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Factorial 6 is 720 
  
PL/SQL procedure successfully completed.
</span>

PL / SQL - 游标

在本章中,我们将讨论PL / SQL中的游标。Oracle创建了一个内存区域,称为上下文区域,用于处理SQL语句,该语句包含处理语句所需的所有信息; 例如,处理的行数等

光标是一个指向这个上下文区域。PL / SQL通过游标控制上下文区域。游标保存SQL语句返回的行(一个或多个)。光标所持有的行集称为活动集

您可以命名游标,以便可以在程序中引用它以一次一个地获取和处理SQL语句返回的行。游标有两种类型 -

  • 隐含游标
  • 显式游标

隐含游标

每当执行SQL语句时,当语句没有显式游标时,Oracle会自动创建隐式游标。程序员无法控制隐式游标及其中的信息。

每当发出DML语句(INSERT,UPDATE和DELETE)时,隐式游标都与此语句相关联。对于INSERT操作,游标保存需要插入的数据。对于UPDATE和DELETE操作,游标标识将受影响的行。

在PL / SQL中,您可以将最新的隐式游标称为SQL游标,它始终具有%FOUND,%ISOPEN,%NOTFOUND%ROWCOUNT等属性。SQL游标具有其他属性,%BULK_ROWCOUNT%BULK_EXCEPTIONS,旨在与FORALL语句一起使用。下表提供了最常用属性的说明 -

S.No 属性和描述
1

%FOUND

如果INSERT,UPDATE或DELETE语句影响一行或多行或SELECT INTO语句返回一行或多行,则返回TRUE。否则,它返回FALSE。

2

%未找到

与%FOUND完全相反。如果INSERT,UPDATE或DELETE语句不影响任何行,或者SELECT INTO语句未返回任何行,则返回TRUE。否则,它返回FALSE。

3

%开了

对于隐式游标,始终返回FALSE,因为Oracle在执行其关联的SQL语句后会自动关闭SQL游标。

4

%ROWCOUNT

返回受INSERT,UPDATE或DELETE语句影响的行数,或SELECT INTO语句返回的行数。

任何SQL游标属性都将作为sql%attribute_name访问,如下例所示。

我们将使用我们在前面章节中创建和使用的CUSTOMERS表。

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+
</span>

以下程序将更新表并将每个客户的工资增加500,并使用SQL%ROWCOUNT属性确定受影响的行数 -

<span style="color:#313131">DECLARE  
   total_rows number<span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   UPDATE customers 
   SET salary <span style="color:#666600">=</span> salary <span style="color:#666600">+</span> <span style="color:#006666">500</span><span style="color:#666600">;</span> 
   IF sql<span style="color:#666600">%</span>notfound THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'no customers selected'</span><span style="color:#666600">);</span> 
   ELSIF sql<span style="color:#666600">%</span>found THEN 
      total_rows <span style="color:#666600">:=</span> sql<span style="color:#666600">%</span>rowcount<span style="color:#666600">;</span>
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span> total_rows <span style="color:#666600">||</span> <span style="color:#008800">' customers selected '</span><span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span>  
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>      </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">6 customers selected  

PL/SQL procedure successfully completed. 
</span>

如果您检查customers表中的记录,您会发现行已更新 -

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2500.00 | 
|  2 | Khilan   |  25 | Delhi     |  2000.00 | 
|  3 | kaushik  |  23 | Kota      |  2500.00 | 
|  4 | Chaitali |  25 | Mumbai    |  7000.00 | 
|  5 | Hardik   |  27 | Bhopal    |  9000.00 | 
|  6 | Komal    |  22 | MP        |  5000.00 | 
+----+----------+-----+-----------+----------+
</span>

显式游标

显式游标是程序员定义的游标,用于获得对上下文区域的更多控制。应在PL / SQL块的声明部分中定义显式游标。它是在SELECT语句上创建的,它返回多行。

创建显式游标的语法是 -

<span style="color:#313131">CURSOR cursor_name IS select_statement; 
</span>

使用显式游标包括以下步骤 -

  • 声明游标以初始化内存
  • 打开光标以分配内存
  • 获取光标以检索数据
  • 关闭游标以释放分配的内存

声明光标

声明游标使用名称和关联的SELECT语句定义游标。例如 -

<span style="color:#313131">CURSOR c_customers IS 
   SELECT id<span style="color:#666600">,</span> name<span style="color:#666600">,</span> address FROM customers<span style="color:#666600">;</span> </span>

打开光标

打开游标会为游标分配内存,并准备好将SQL语句返回的行提取到游标中。例如,我们将按如下方式打开上面定义的游标 -

<span style="color:#313131">OPEN c_customers<span style="color:#666600">;</span> </span>

获取光标

获取光标涉及一次访问一行。例如,我们将从上面打开的游标中获取行,如下所示 -

<span style="color:#313131">FETCH c_customers INTO c_id<span style="color:#666600">,</span> c_name<span style="color:#666600">,</span> c_addr<span style="color:#666600">;</span> </span>

关闭光标

关闭光标意味着释放分配的内存。例如,我们将关闭上面打开的游标,如下所示 -

<span style="color:#313131">CLOSE c_customers<span style="color:#666600">;</span></span>

以下是一个完整的例子来说明显式游标和minua的概念;

<span style="color:#313131">DECLARE 
   c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_name customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   CURSOR c_customers <span style="color:#000088">is</span> 
      SELECT id<span style="color:#666600">,</span> name<span style="color:#666600">,</span> address FROM customers<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   OPEN c_customers<span style="color:#666600">;</span> 
   LOOP 
   FETCH c_customers <span style="color:#000088">into</span> c_id<span style="color:#666600">,</span> c_name<span style="color:#666600">,</span> c_addr<span style="color:#666600">;</span> 
      EXIT WHEN c_customers<span style="color:#666600">%</span>notfound<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>c_id <span style="color:#666600">||</span> <span style="color:#008800">' '</span> <span style="color:#666600">||</span> c_name <span style="color:#666600">||</span> <span style="color:#008800">' '</span> <span style="color:#666600">||</span> c_addr<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
   CLOSE c_customers<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">1 Ramesh Ahmedabad  
2 Khilan Delhi  
3 kaushik Kota     
4 Chaitali Mumbai  
5 Hardik Bhopal   
6 Komal MP  
  
PL/SQL procedure successfully completed. 
</span>

PL / SQL - 记录

在本章中,我们将讨论PL / SQL中的记录。一个记录是一种数据结构,可容纳不同种类的数据项。记录由不同的字段组成,类似于数据库表的一行。

例如,您希望在库中跟踪您的图书。您可能希望跟踪每本书的以下属性,例如标题,作者,主题,书籍ID。包含每个项目的字段的记录允许将BOOK视为逻辑单元,并允许您以更好的方式组织和表示其信息。

PL / SQL可以处理以下类型的记录 -

  • 基于表格的
  • 基于游标的记录
  • 用户定义的记录

基于表的记录

该ROWTYPE%属性使程序员能够创建基于表cursorbased记录。

以下示例说明了基于表的记录的概念。我们将使用我们在前面章节中创建和使用的CUSTOMERS表 -

<span style="color:#313131">DECLARE 
   customer_rec customers<span style="color:#666600">%</span>rowtype<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   SELECT <span style="color:#666600">*</span> <span style="color:#000088">into</span> customer_rec 
   FROM customers 
   WHERE id <span style="color:#666600">=</span> <span style="color:#006666">5</span><span style="color:#666600">;</span>  
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer ID: '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>id<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer Name: '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>name<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer Address: '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>address<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer Salary: '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>salary<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Customer ID: 5 
Customer Name: Hardik 
Customer Address: Bhopal 
Customer Salary: 9000 
 
PL/SQL procedure successfully completed.
</span>

基于游标的记录

以下示例说明了基于游标的记录的概念。我们将使用我们在前面章节中创建和使用的CUSTOMERS表 -

<span style="color:#313131">DECLARE 
   CURSOR customer_cur <span style="color:#000088">is</span> 
      SELECT id<span style="color:#666600">,</span> name<span style="color:#666600">,</span> address  
      FROM customers<span style="color:#666600">;</span> 
   customer_rec customer_cur<span style="color:#666600">%</span>rowtype<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   OPEN customer_cur<span style="color:#666600">;</span> 
   LOOP 
      FETCH customer_cur <span style="color:#000088">into</span> customer_rec<span style="color:#666600">;</span> 
      EXIT WHEN customer_cur<span style="color:#666600">%</span>notfound<span style="color:#666600">;</span> 
      DBMS_OUTPUT<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>customer_rec<span style="color:#666600">.</span>id <span style="color:#666600">||</span> <span style="color:#008800">' '</span> <span style="color:#666600">||</span> customer_rec<span style="color:#666600">.</span>name<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">1 Ramesh 
2 Khilan 
3 kaushik 
4 Chaitali 
5 Hardik 
6 Komal  

PL/SQL procedure successfully completed. 
</span>

用户定义的记录

PL / SQL提供了一个用户定义的记录类型,允许您定义不同的记录结构。这些记录包含不同的字段。假设您想要在图书馆中跟踪您的图书。您可能希望跟踪每本书的以下属性 -

  • 标题
  • 作者
  • 学科
  • 书名

定义记录

记录类型定义为 -

<span style="color:#313131">TYPE 
type_name IS RECORD 
  ( field_name1  datatype1  [NOT NULL]  [:= DEFAULT EXPRESSION], 
   field_name2   datatype2   [NOT NULL]  [:= DEFAULT EXPRESSION], 
   ... 
   field_nameN  datatypeN  [NOT NULL]  [:= DEFAULT EXPRESSION); 
record-name  type_name;
</span>

Book记录以下列方式声明 -

<span style="color:#313131">DECLARE 
TYPE books IS RECORD 
<span style="color:#666600">(</span>title  varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
   author  varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
   subject varchar<span style="color:#666600">(</span><span style="color:#006666">100</span><span style="color:#666600">),</span> 
   book_id   number<span style="color:#666600">);</span> 
book1 books<span style="color:#666600">;</span> 
book2 books<span style="color:#666600">;</span> </span>

访问字段

要访问记录的任何字段,我们使用点(。)运算符。成员访问运算符被编码为记录变量名称和我们希望访问的字段之间的句点。以下是解释记录用法的示例 -

<span style="color:#313131">DECLARE 
   type books <span style="color:#000088">is</span> record 
      <span style="color:#666600">(</span>title varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
      author varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
      subject varchar<span style="color:#666600">(</span><span style="color:#006666">100</span><span style="color:#666600">),</span> 
      book_id number<span style="color:#666600">);</span> 
   book1 books<span style="color:#666600">;</span> 
   book2 books<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600">--</span> <span style="color:#7f0055">Book</span> <span style="color:#006666">1</span> specification 
   book1<span style="color:#666600">.</span>title  <span style="color:#666600">:=</span> <span style="color:#008800">'C Programming'</span><span style="color:#666600">;</span> 
   book1<span style="color:#666600">.</span>author <span style="color:#666600">:=</span> <span style="color:#008800">'Nuha Ali '</span><span style="color:#666600">;</span>  
   book1<span style="color:#666600">.</span>subject <span style="color:#666600">:=</span> <span style="color:#008800">'C Programming Tutorial'</span><span style="color:#666600">;</span> 
   book1<span style="color:#666600">.</span>book_id <span style="color:#666600">:=</span> <span style="color:#006666">6495407</span><span style="color:#666600">;</span>  
   <span style="color:#666600">--</span> <span style="color:#7f0055">Book</span> <span style="color:#006666">2</span> specification 
   book2<span style="color:#666600">.</span>title <span style="color:#666600">:=</span> <span style="color:#008800">'Telecom Billing'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>author <span style="color:#666600">:=</span> <span style="color:#008800">'Zara Ali'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>subject <span style="color:#666600">:=</span> <span style="color:#008800">'Telecom Billing Tutorial'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>book_id <span style="color:#666600">:=</span> <span style="color:#006666">6495700</span><span style="color:#666600">;</span>  
  
  <span style="color:#666600">--</span> <span style="color:#7f0055">Print</span> book <span style="color:#006666">1</span> record 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 1 title : '</span><span style="color:#666600">||</span> book1<span style="color:#666600">.</span>title<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 1 author : '</span><span style="color:#666600">||</span> book1<span style="color:#666600">.</span>author<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 1 subject : '</span><span style="color:#666600">||</span> book1<span style="color:#666600">.</span>subject<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 1 book_id : '</span> <span style="color:#666600">||</span> book1<span style="color:#666600">.</span>book_id<span style="color:#666600">);</span> 
   
   <span style="color:#666600">--</span> <span style="color:#7f0055">Print</span> book <span style="color:#006666">2</span> record 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 2 title : '</span><span style="color:#666600">||</span> book2<span style="color:#666600">.</span>title<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 2 author : '</span><span style="color:#666600">||</span> book2<span style="color:#666600">.</span>author<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 2 subject : '</span><span style="color:#666600">||</span> book2<span style="color:#666600">.</span>subject<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book 2 book_id : '</span><span style="color:#666600">||</span> book2<span style="color:#666600">.</span>book_id<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Book 1 title : C Programming 
Book 1 author : Nuha Ali 
Book 1 subject : C Programming Tutorial 
Book 1 book_id : 6495407 
Book 2 title : Telecom Billing 
Book 2 author : Zara Ali 
Book 2 subject : Telecom Billing Tutorial 
Book 2 book_id : 6495700  

PL/SQL procedure successfully completed. 
</span>

记录为子程序参数

您可以将记录作为子程序参数传递,就像传递任何其他变量一样。您也可以按照上面示例中访问的方式访问记录字段 -

<span style="color:#313131">DECLARE 
   type books <span style="color:#000088">is</span> record 
      <span style="color:#666600">(</span>title  varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
      author  varchar<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">),</span> 
      subject varchar<span style="color:#666600">(</span><span style="color:#006666">100</span><span style="color:#666600">),</span> 
      book_id   number<span style="color:#666600">);</span> 
   book1 books<span style="color:#666600">;</span> 
   book2 books<span style="color:#666600">;</span>  
PROCEDURE printbook <span style="color:#666600">(</span>book books<span style="color:#666600">)</span> IS 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line <span style="color:#666600">(</span><span style="color:#008800">'Book  title :  '</span> <span style="color:#666600">||</span> book<span style="color:#666600">.</span>title<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Book  author : '</span> <span style="color:#666600">||</span> book<span style="color:#666600">.</span>author<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span> <span style="color:#008800">'Book  subject : '</span> <span style="color:#666600">||</span> book<span style="color:#666600">.</span>subject<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span> <span style="color:#008800">'Book book_id : '</span> <span style="color:#666600">||</span> book<span style="color:#666600">.</span>book_id<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
   
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600">--</span> <span style="color:#7f0055">Book</span> <span style="color:#006666">1</span> specification 
   book1<span style="color:#666600">.</span>title  <span style="color:#666600">:=</span> <span style="color:#008800">'C Programming'</span><span style="color:#666600">;</span> 
   book1<span style="color:#666600">.</span>author <span style="color:#666600">:=</span> <span style="color:#008800">'Nuha Ali '</span><span style="color:#666600">;</span>  
   book1<span style="color:#666600">.</span>subject <span style="color:#666600">:=</span> <span style="color:#008800">'C Programming Tutorial'</span><span style="color:#666600">;</span> 
   book1<span style="color:#666600">.</span>book_id <span style="color:#666600">:=</span> <span style="color:#006666">6495407</span><span style="color:#666600">;</span>
   
   <span style="color:#666600">--</span> <span style="color:#7f0055">Book</span> <span style="color:#006666">2</span> specification 
   book2<span style="color:#666600">.</span>title <span style="color:#666600">:=</span> <span style="color:#008800">'Telecom Billing'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>author <span style="color:#666600">:=</span> <span style="color:#008800">'Zara Ali'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>subject <span style="color:#666600">:=</span> <span style="color:#008800">'Telecom Billing Tutorial'</span><span style="color:#666600">;</span> 
   book2<span style="color:#666600">.</span>book_id <span style="color:#666600">:=</span> <span style="color:#006666">6495700</span><span style="color:#666600">;</span>  
   
   <span style="color:#666600">--</span> <span style="color:#7f0055">Use</span> procedure to <span style="color:#000088">print</span> book info 
   printbook<span style="color:#666600">(</span>book1<span style="color:#666600">);</span> 
   printbook<span style="color:#666600">(</span>book2<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Book  title : C Programming 
Book  author : Nuha Ali 
Book subject : C Programming Tutorial 
Book  book_id : 6495407 
Book title : Telecom Billing 
Book author : Zara Ali 
Book subject : Telecom Billing Tutorial 
Book book_id : 6495700  

PL/SQL procedure successfully completed. 
</span>

PL / SQL - 例外

在本章中,我们将讨论PL / SQL中的异常。程序执行期间的错误条件是一个例外。PL / SQL支持程序员在程序中使用EXCEPTION块捕获这些条件,并对错误条件采取适当的操作。有两种类型的例外 -

  • 系统定义的异常
  • 用户定义的异常

异常处理的语法

异常处理的一般语法如下。在这里,您可以列出尽可能多的例外情况。默认例外将使用WHEN其他人处理- 那么 -

<span style="color:#313131">DECLARE 
   <span style="color:#666600"><</span>declarations section<span style="color:#666600">></span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600"><</span>executable command<span style="color:#666600">(</span>s<span style="color:#666600">)></span> 
EXCEPTION 
   <span style="color:#666600"><</span>exception handling goes here <span style="color:#666600">></span> 
   WHEN exception1 THEN  
      exception1<span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements  
   WHEN exception2  THEN  
      exception2<span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements  
   WHEN exception3 THEN  
      exception3<span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements 
   <span style="color:#666600">........</span> 
   WHEN others THEN 
      exception3<span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements 
<span style="color:#000088">END</span><span style="color:#666600">;</span></span>

让我们编写一个代码来说明这个概念。我们将使用我们在前面章节中创建和使用的CUSTOMERS表 -

<span style="color:#313131">DECLARE 
   c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type <span style="color:#666600">:=</span> <span style="color:#006666">8</span><span style="color:#666600">;</span> 
   c_name customerS<span style="color:#666600">.</span><span style="color:#7f0055">Name</span><span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   SELECT  name<span style="color:#666600">,</span> address INTO  c_name<span style="color:#666600">,</span> c_addr 
   FROM customers 
   WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span>  
   DBMS_OUTPUT<span style="color:#666600">.</span>PUT_LINE <span style="color:#666600">(</span><span style="color:#008800">'Name: '</span><span style="color:#666600">||</span>  c_name<span style="color:#666600">);</span> 
   DBMS_OUTPUT<span style="color:#666600">.</span>PUT_LINE <span style="color:#666600">(</span><span style="color:#008800">'Address: '</span> <span style="color:#666600">||</span> c_addr<span style="color:#666600">);</span> 

EXCEPTION 
   WHEN no_data_found THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'No such customer!'</span><span style="color:#666600">);</span> 
   WHEN others THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Error!'</span><span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">No such customer!  

PL/SQL procedure successfully completed. 
</span>

上述程序显示ID已给出的客户的名称和地址。由于我们的数据库中没有ID值为8的客户,程序会引发运行时异常NO_DATA_FOUND,该异常在EXCEPTION块中捕获。

提高例外

只要存在任何内部数据库错误,数据库服务器就会自动引发异常,但程序员可以使用命令RAISE显式引发异常。以下是引发异常的简单语法 -

<span style="color:#313131">DECLARE 
   exception_name EXCEPTION<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   IF condition THEN 
      RAISE exception_name<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
EXCEPTION 
   WHEN exception_name THEN 
   statement<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> </span>

您可以使用上述语法来引发Oracle标准异常或任何用户定义的异常。在下一节中,我们将举例说明如何引发用户定义的异常。您可以以类似的方式引发Oracle标准异常。

用户定义的异常

PL / SQL允许您根据程序的需要定义自己的异常。必须声明用户定义的异常,然后使用RAISE语句或过程DBMS_STANDARD.RAISE_APPLICATION_ERROR显式引发。

声明异常的语法是 -

<span style="color:#313131">DECLARE 
   my-exception EXCEPTION; 
</span>

以下示例说明了该概念。该程序询问客户ID,当用户输入无效ID时,引发异常invalid_id

<span style="color:#313131">DECLARE 
   c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type <span style="color:#666600">:=</span> <span style="color:#666600">&</span>cc_id<span style="color:#666600">;</span> 
   c_name customerS<span style="color:#666600">.</span><span style="color:#7f0055">Name</span><span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">;</span>  
   <span style="color:#666600">--</span> user <span style="color:#000088">defined</span> exception 
   ex_invalid_id  EXCEPTION<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   IF c_id <span style="color:#666600"><=</span> <span style="color:#006666">0</span> THEN 
      RAISE ex_invalid_id<span style="color:#666600">;</span> 
   ELSE 
      SELECT  name<span style="color:#666600">,</span> address INTO  c_name<span style="color:#666600">,</span> c_addr 
      FROM customers 
      WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span>
      DBMS_OUTPUT<span style="color:#666600">.</span>PUT_LINE <span style="color:#666600">(</span><span style="color:#008800">'Name: '</span><span style="color:#666600">||</span>  c_name<span style="color:#666600">);</span>  
      DBMS_OUTPUT<span style="color:#666600">.</span>PUT_LINE <span style="color:#666600">(</span><span style="color:#008800">'Address: '</span> <span style="color:#666600">||</span> c_addr<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 

EXCEPTION 
   WHEN ex_invalid_id THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'ID must be greater than zero!'</span><span style="color:#666600">);</span> 
   WHEN no_data_found THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'No such customer!'</span><span style="color:#666600">);</span> 
   WHEN others THEN 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Error!'</span><span style="color:#666600">);</span>  
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Enter value for cc_id: -6 (let's enter a value -6) 
old  2: c_id customers.id%type := &cc_id; 
new  2: c_id customers.id%type := -6; 
ID must be greater than zero! 
 
PL/SQL procedure successfully completed. 
</span>

预定义的例外

PL / SQL提供了许多预定义的异常,这些异常在程序违反任何数据库规则时执行。例如,当SELECT INTO语句不返回任何行时,将引发预定义的异常NO_DATA_FOUND。下表列出了一些重要的预定义例外情况 -

例外 Oracle错误 SQLCODE 描述
ACCESS_INTO_NULL 06530 -6530 在为空对象自动分配值时引发它。
CASE_NOT_FOUND 06592 -6592 It is raised when none of the choices in the WHEN clause of a CASE statement is selected, and there is no ELSE clause.
COLLECTION_IS_NULL 06531 -6531 It is raised when a program attempts to apply collection methods other than EXISTS to an uninitialized nested table or varray, or the program attempts to assign values to the elements of an uninitialized nested table or varray.
DUP_VAL_ON_INDEX 00001 -1 It is raised when duplicate values are attempted to be stored in a column with unique index.
INVALID_CURSOR 01001 -1001 It is raised when attempts are made to make a cursor operation that is not allowed, such as closing an unopened cursor.
INVALID_NUMBER 01722 -1722 It is raised when the conversion of a character string into a number fails because the string does not represent a valid number.
LOGIN_DENIED 01017 -1017 It is raised when a program attempts to log on to the database with an invalid username or password.
NO_DATA_FOUND 01403 +100 It is raised when a SELECT INTO statement returns no rows.
NOT_LOGGED_ON 01012 -1012 It is raised when a database call is issued without being connected to the database.
PROGRAM_ERROR 06501 -6501 It is raised when PL/SQL has an internal problem.
ROWTYPE_MISMATCH 06504 -6504 It is raised when a cursor fetches value in a variable having incompatible data type.
SELF_IS_NULL 30625 -30625 It is raised when a member method is invoked, but the instance of the object type was not initialized.
STORAGE_ERROR 06500 -6500 It is raised when PL/SQL ran out of memory or memory was corrupted.
TOO_MANY_ROWS 01422 -1422 It is raised when a SELECT INTO statement returns more than one row.
VALUE_ERROR 06502 -6502 It is raised when an arithmetic, conversion, truncation, or sizeconstraint error occurs.
ZERO_DIVIDE 01476 1476 It is raised when an attempt is made to divide a number by zero.

PL/SQL - Triggers

In this chapter, we will discuss Triggers in PL/SQL. Triggers are stored programs, which are automatically executed or fired when some events occur. Triggers are, in fact, written to be executed in response to any of the following events −

  • database manipulation (DML) statement (DELETE, INSERT, or UPDATE)

  • database definition (DDL) statement (CREATE, ALTER, or DROP).

  • database operation (SERVERERROR, LOGON, LOGOFF, STARTUP, or SHUTDOWN).

Triggers can be defined on the table, view, schema, or database with which the event is associated.

Benefits of Triggers

Triggers can be written for the following purposes −

  • Generating some derived column values automatically
  • Enforcing referential integrity
  • Event logging and storing information on table access
  • Auditing
  • Synchronous replication of tables
  • Imposing security authorizations
  • Preventing invalid transactions

Creating Triggers

The syntax for creating a trigger is −

<span style="color:#313131">CREATE <span style="color:#666600">[</span>OR REPLACE <span style="color:#666600">]</span> TRIGGER trigger_name  
<span style="color:#666600">{</span>BEFORE <span style="color:#666600">|</span> AFTER <span style="color:#666600">|</span> INSTEAD OF <span style="color:#666600">}</span>  
<span style="color:#666600">{</span>INSERT <span style="color:#666600">[</span>OR<span style="color:#666600">]</span> <span style="color:#666600">|</span> UPDATE <span style="color:#666600">[</span>OR<span style="color:#666600">]</span> <span style="color:#666600">|</span> DELETE<span style="color:#666600">}</span>  
<span style="color:#666600">[</span>OF col_name<span style="color:#666600">]</span>  
ON table_name  
<span style="color:#666600">[</span>REFERENCING OLD AS o NEW AS n<span style="color:#666600">]</span>  
<span style="color:#666600">[</span>FOR EACH ROW<span style="color:#666600">]</span>  
WHEN <span style="color:#666600">(</span>condition<span style="color:#666600">)</span>   
DECLARE 
   <span style="color:#7f0055">Declaration</span><span style="color:#666600">-</span>statements 
<span style="color:#000088">BEGIN</span>  
   <span style="color:#7f0055">Executable</span><span style="color:#666600">-</span>statements 
EXCEPTION 
   <span style="color:#7f0055">Exception</span><span style="color:#666600">-</span>handling<span style="color:#666600">-</span>statements 
<span style="color:#000088">END</span><span style="color:#666600">;</span> </span>

Where,

  • CREATE [OR REPLACE] TRIGGER trigger_name − Creates or replaces an existing trigger with the trigger_name.

  • {BEFORE | AFTER | INSTEAD OF} − This specifies when the trigger will be executed. The INSTEAD OF clause is used for creating trigger on a view.

  • {INSERT [OR] | UPDATE [OR] | DELETE} − This specifies the DML operation.

  • [OF col_name] − This specifies the column name that will be updated.

  • [ON table_name] − This specifies the name of the table associated with the trigger.

  • [REFERENCING OLD AS o NEW AS n] − This allows you to refer new and old values for various DML statements, such as INSERT, UPDATE, and DELETE.

  • [FOR EACH ROW] − This specifies a row-level trigger, i.e., the trigger will be executed for each row being affected. Otherwise the trigger will execute just once when the SQL statement is executed, which is called a table level trigger.

  • WHEN (condition) − This provides a condition for rows for which the trigger would fire. This clause is valid only for row-level triggers.

Example

To start with, we will be using the CUSTOMERS table we had created and used in the previous chapters −

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+ 
</span>

The following program creates a row-level trigger for the customers table that would fire for INSERT or UPDATE or DELETE operations performed on the CUSTOMERS table. This trigger will display the salary difference between the old values and new values −

<span style="color:#313131">CREATE OR REPLACE TRIGGER display_salary_changes 
BEFORE DELETE OR INSERT OR UPDATE ON customers 
FOR EACH ROW 
WHEN <span style="color:#666600">(</span>NEW<span style="color:#666600">.</span>ID <span style="color:#666600">></span> <span style="color:#006666">0</span><span style="color:#666600">)</span> 
DECLARE 
   sal_diff number<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   sal_diff <span style="color:#666600">:=</span> <span style="color:#666600">:</span>NEW<span style="color:#666600">.</span>salary  <span style="color:#666600">-</span> <span style="color:#666600">:</span>OLD<span style="color:#666600">.</span>salary<span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Old salary: '</span> <span style="color:#666600">||</span> <span style="color:#666600">:</span>OLD<span style="color:#666600">.</span>salary<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'New salary: '</span> <span style="color:#666600">||</span> <span style="color:#666600">:</span>NEW<span style="color:#666600">.</span>salary<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Salary difference: '</span> <span style="color:#666600">||</span> sal_diff<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Trigger created.
</span>

The following points need to be considered here −

  • OLD and NEW references are not available for table-level triggers, rather you can use them for record-level triggers.

  • If you want to query the table in the same trigger, then you should use the AFTER keyword, because triggers can query the table or change it again only after the initial changes are applied and the table is back in a consistent state.

  • The above trigger has been written in such a way that it will fire before any DELETE or INSERT or UPDATE operation on the table, but you can write your trigger on a single or multiple operations, for example BEFORE DELETE, which will fire whenever a record will be deleted using the DELETE operation on the table.

Triggering a Trigger

Let us perform some DML operations on the CUSTOMERS table. Here is one INSERT statement, which will create a new record in the table −

<span style="color:#313131">INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#008800">'Kriti'</span><span style="color:#666600">,</span> <span style="color:#006666">22</span><span style="color:#666600">,</span> <span style="color:#008800">'HP'</span><span style="color:#666600">,</span> <span style="color:#006666">7500.00</span> <span style="color:#666600">);</span> </span>

When a record is created in the CUSTOMERS table, the above create trigger, display_salary_changes will be fired and it will display the following result −

<span style="color:#313131">Old salary: 
New salary: 7500 
Salary difference:
</span>

Because this is a new record, old salary is not available and the above result comes as null. Let us now perform one more DML operation on the CUSTOMERS table. The UPDATE statement will update an existing record in the table −

<span style="color:#313131">UPDATE customers 
SET salary <span style="color:#666600">=</span> salary <span style="color:#666600">+</span> <span style="color:#006666">500</span> 
WHERE id <span style="color:#666600">=</span> <span style="color:#006666">2</span><span style="color:#666600">;</span> </span>

When a record is updated in the CUSTOMERS table, the above create trigger, display_salary_changes will be fired and it will display the following result −

<span style="color:#313131">Old salary: 1500 
New salary: 2000 
Salary difference: 500 
</span>

PL/SQL - Packages

In this chapter, we will discuss the Packages in PL/SQL. Packages are schema objects that groups logically related PL/SQL types, variables, and subprograms.

A package will have two mandatory parts −

  • Package specification
  • Package body or definition

Package Specification

The specification is the interface to the package. It just DECLARES the types, variables, constants, exceptions, cursors, and subprograms that can be referenced from outside the package. In other words, it contains all information about the content of the package, but excludes the code for the subprograms.

All objects placed in the specification are called public objects. Any subprogram not in the package specification but coded in the package body is called a private object.

The following code snippet shows a package specification having a single procedure. You can have many global variables defined and multiple procedures or functions inside a package.

<span style="color:#313131">CREATE PACKAGE cust_sal AS 
   PROCEDURE find_sal<span style="color:#666600">(</span>c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">);</span> 
<span style="color:#000088">END</span> cust_sal<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Package created.
</span>

Package Body

The package body has the codes for various methods declared in the package specification and other private declarations, which are hidden from the code outside the package.

The CREATE PACKAGE BODY Statement is used for creating the package body. The following code snippet shows the package body declaration for the cust_sal package created above. I assumed that we already have CUSTOMERS table created in our database as mentioned in the PL/SQL - Variables chapter.

<span style="color:#313131">CREATE OR REPLACE PACKAGE BODY cust_sal AS  
   
   PROCEDURE find_sal<span style="color:#666600">(</span>c_id customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>TYPE<span style="color:#666600">)</span> IS 
   c_sal customers<span style="color:#666600">.</span>salary<span style="color:#666600">%</span>TYPE<span style="color:#666600">;</span> 
   <span style="color:#000088">BEGIN</span> 
      SELECT salary INTO c_sal 
      FROM customers 
      WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Salary: '</span><span style="color:#666600">||</span> c_sal<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> find_sal<span style="color:#666600">;</span> 
<span style="color:#000088">END</span> cust_sal<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Package body created.
</span>

Using the Package Elements

The package elements (variables, procedures or functions) are accessed with the following syntax −

<span style="color:#313131">package_name.element_name;
</span>

Consider, we already have created the above package in our database schema, the following program uses the find_sal method of the cust_salpackage −

<span style="color:#313131">DECLARE 
   code customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type <span style="color:#666600">:=</span> <span style="color:#666600">&</span>cc_id<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   cust_sal<span style="color:#666600">.</span>find_sal<span style="color:#666600">(</span>code<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

When the above code is executed at the SQL prompt, it prompts to enter the customer ID and when you enter an ID, it displays the corresponding salary as follows −

<span style="color:#313131">Enter value for cc_id: 1 
Salary: 3000 

PL/SQL procedure successfully completed. 
</span>

Example

The following program provides a more complete package. We will use the CUSTOMERS table stored in our database with the following records −

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  3000.00 | 
|  2 | Khilan   |  25 | Delhi     |  3000.00 | 
|  3 | kaushik  |  23 | Kota      |  3000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  7500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  9500.00 | 
|  6 | Komal    |  22 | MP        |  5500.00 | 
+----+----------+-----+-----------+----------+
</span>

The Package Specification

<span style="color:#313131">CREATE OR REPLACE PACKAGE c_package AS 
   <span style="color:#666600">--</span> <span style="color:#7f0055">Adds</span> a customer 
   PROCEDURE addCustomer<span style="color:#666600">(</span>c_id   customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
   c_name  customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
   c_age  customers<span style="color:#666600">.</span>age<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
   c_addr customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">,</span>  
   c_sal  customers<span style="color:#666600">.</span>salary<span style="color:#666600">%</span>type<span style="color:#666600">);</span> 
   
   <span style="color:#666600">--</span> <span style="color:#7f0055">Removes</span> a customer 
   PROCEDURE delCustomer<span style="color:#666600">(</span>c_id  customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>TYPE<span style="color:#666600">);</span> 
   <span style="color:#666600">--</span><span style="color:#7f0055">Lists</span> all customers 
   PROCEDURE listCustomer<span style="color:#666600">;</span> 
  
<span style="color:#000088">END</span> c_package<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

When the above code is executed at the SQL prompt, it creates the above package and displays the following result −

<span style="color:#313131">Package created.
</span>

Creating the Package Body

<span style="color:#313131">CREATE OR REPLACE PACKAGE BODY c_package AS 
   PROCEDURE addCustomer<span style="color:#666600">(</span>c_id  customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
      c_name customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
      c_age  customers<span style="color:#666600">.</span>age<span style="color:#666600">%</span>type<span style="color:#666600">,</span> 
      c_addr  customers<span style="color:#666600">.</span>address<span style="color:#666600">%</span>type<span style="color:#666600">,</span>  
      c_sal   customers<span style="color:#666600">.</span>salary<span style="color:#666600">%</span>type<span style="color:#666600">)</span> 
   IS 
   <span style="color:#000088">BEGIN</span> 
      INSERT INTO customers <span style="color:#666600">(</span>id<span style="color:#666600">,</span>name<span style="color:#666600">,</span>age<span style="color:#666600">,</span>address<span style="color:#666600">,</span>salary<span style="color:#666600">)</span> 
         VALUES<span style="color:#666600">(</span>c_id<span style="color:#666600">,</span> c_name<span style="color:#666600">,</span> c_age<span style="color:#666600">,</span> c_addr<span style="color:#666600">,</span> c_sal<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> addCustomer<span style="color:#666600">;</span> 
   
   PROCEDURE delCustomer<span style="color:#666600">(</span>c_id   customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">)</span> IS 
   <span style="color:#000088">BEGIN</span> 
      DELETE FROM customers 
      WHERE id <span style="color:#666600">=</span> c_id<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> delCustomer<span style="color:#666600">;</span>  
   
   PROCEDURE listCustomer IS 
   CURSOR c_customers <span style="color:#000088">is</span> 
      SELECT  name FROM customers<span style="color:#666600">;</span> 
   TYPE c_list <span style="color:#000088">is</span> TABLE OF customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   name_list c_list <span style="color:#666600">:=</span> c_list<span style="color:#666600">();</span> 
   counter integer <span style="color:#666600">:=</span><span style="color:#006666">0</span><span style="color:#666600">;</span> 
   <span style="color:#000088">BEGIN</span> 
      FOR n IN c_customers LOOP 
      counter <span style="color:#666600">:=</span> counter <span style="color:#666600">+</span><span style="color:#006666">1</span><span style="color:#666600">;</span> 
      name_list<span style="color:#666600">.</span>extend<span style="color:#666600">;</span> 
      name_list<span style="color:#666600">(</span>counter<span style="color:#666600">)</span> <span style="color:#666600">:=</span> n<span style="color:#666600">.</span>name<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer('</span> <span style="color:#666600">||</span>counter<span style="color:#666600">||</span> <span style="color:#008800">')'</span><span style="color:#666600">||</span>name_list<span style="color:#666600">(</span>counter<span style="color:#666600">));</span> 
      <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> listCustomer<span style="color:#666600">;</span>
   
<span style="color:#000088">END</span> c_package<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

The above example makes use of the nested table. We will discuss the concept of nested table in the next chapter.

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Package body created.
</span>

Using The Package

The following program uses the methods declared and defined in the package c_package.

<span style="color:#313131">DECLARE 
   code customers<span style="color:#666600">.</span>id<span style="color:#666600">%</span>type<span style="color:#666600">:=</span> <span style="color:#006666">8</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   c_package<span style="color:#666600">.</span>addcustomer<span style="color:#666600">(</span><span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#008800">'Rajnish'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Chennai'</span><span style="color:#666600">,</span> <span style="color:#006666">3500</span><span style="color:#666600">);</span> 
   c_package<span style="color:#666600">.</span>addcustomer<span style="color:#666600">(</span><span style="color:#006666">8</span><span style="color:#666600">,</span> <span style="color:#008800">'Subham'</span><span style="color:#666600">,</span> <span style="color:#006666">32</span><span style="color:#666600">,</span> <span style="color:#008800">'Delhi'</span><span style="color:#666600">,</span> <span style="color:#006666">7500</span><span style="color:#666600">);</span> 
   c_package<span style="color:#666600">.</span>listcustomer<span style="color:#666600">;</span> 
   c_package<span style="color:#666600">.</span>delcustomer<span style="color:#666600">(</span>code<span style="color:#666600">);</span> 
   c_package<span style="color:#666600">.</span>listcustomer<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal 
Customer(7): Rajnish 
Customer(8): Subham 
Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal
Customer(7): Rajnish 

PL/SQL procedure successfully completed 
</span>

PL/SQL - Collections

In this chapter, we will discuss the Collections in PL/SQL. A collection is an ordered group of elements having the same data type. Each element is identified by a unique subscript that represents its position in the collection.

PL/SQL provides three collection types −

  • Index-by tables or Associative array
  • Nested table
  • Variable-size array or Varray

Oracle documentation provides the following characteristics for each type of collections −

Collection Type Number of Elements Subscript Type Dense or Sparse Where Created Can Be Object Type Attribute
Associative array (or index-by table) Unbounded String or integer Either Only in PL/SQL block No
Nested table Unbounded Integer Starts dense, can become sparse Either in PL/SQL block or at schema level Yes
Variablesize array (Varray) Bounded Integer Always dense Either in PL/SQL block or at schema level Yes

We have already discussed varray in the chapter 'PL/SQL arrays'. In this chapter, we will discuss the PL/SQL tables.

Both types of PL/SQL tables, i.e., the index-by tables and the nested tables have the same structure and their rows are accessed using the subscript notation. However, these two types of tables differ in one aspect; the nested tables can be stored in a database column and the index-by tables cannot.

Index-By Table

An index-by table (also called an associative array) is a set of key-valuepairs. Each key is unique and is used to locate the corresponding value. The key can be either an integer or a string.

An index-by table is created using the following syntax. Here, we are creating an index-by table named table_name, the keys of which will be of the subscript_type and associated values will be of the element_type

<span style="color:#313131">TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY subscript_type; 
 
table_name type_name;
</span>

Example

Following example shows how to create a table to store integer values along with names and later it prints the same list of names.

<span style="color:#313131">DECLARE 
   TYPE salary IS TABLE OF NUMBER INDEX BY VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">);</span> 
   salary_list salary<span style="color:#666600">;</span> 
   name   VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">);</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600">--</span> adding elements to the table 
   salary_list<span style="color:#666600">(</span><span style="color:#008800">'Rajnish'</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">62000</span><span style="color:#666600">;</span> 
   salary_list<span style="color:#666600">(</span><span style="color:#008800">'Minakshi'</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">75000</span><span style="color:#666600">;</span> 
   salary_list<span style="color:#666600">(</span><span style="color:#008800">'Martin'</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">100000</span><span style="color:#666600">;</span> 
   salary_list<span style="color:#666600">(</span><span style="color:#008800">'James'</span><span style="color:#666600">)</span> <span style="color:#666600">:=</span> <span style="color:#006666">78000</span><span style="color:#666600">;</span>  
   
   <span style="color:#666600">--</span> printing the table 
   name <span style="color:#666600">:=</span> salary_list<span style="color:#666600">.</span>FIRST<span style="color:#666600">;</span> 
   WHILE name IS NOT <span style="color:#000088">null</span> LOOP 
      dbms_output<span style="color:#666600">.</span>put_line 
      <span style="color:#666600">(</span><span style="color:#008800">'Salary of '</span> <span style="color:#666600">||</span> name <span style="color:#666600">||</span> <span style="color:#008800">' is '</span> <span style="color:#666600">||</span> TO_CHAR<span style="color:#666600">(</span>salary_list<span style="color:#666600">(</span>name<span style="color:#666600">)));</span> 
      name <span style="color:#666600">:=</span> salary_list<span style="color:#666600">.</span>NEXT<span style="color:#666600">(</span>name<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Salary of James is 78000 
Salary of Martin is 100000 
Salary of Minakshi is 75000 
Salary of Rajnish is 62000  

PL/SQL procedure successfully completed.
</span>

Example

Elements of an index-by table could also be a %ROWTYPE of any database table or %TYPE of any database table field. The following example illustrates the concept. We will use the CUSTOMERS table stored in our database as −

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+  
</span>

 

<span style="color:#313131">DECLARE 
   CURSOR c_customers <span style="color:#000088">is</span> 
      <span style="color:#000088">select</span> name <span style="color:#000088">from</span> customers<span style="color:#666600">;</span> 

   TYPE c_list IS TABLE of customers<span style="color:#666600">.</span><span style="color:#7f0055">Name</span><span style="color:#666600">%</span>type INDEX BY binary_integer<span style="color:#666600">;</span> 
   name_list c_list<span style="color:#666600">;</span> 
   counter integer <span style="color:#666600">:=</span><span style="color:#006666">0</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   FOR n IN c_customers LOOP 
      counter <span style="color:#666600">:=</span> counter <span style="color:#666600">+</span><span style="color:#006666">1</span><span style="color:#666600">;</span> 
      name_list<span style="color:#666600">(</span>counter<span style="color:#666600">)</span> <span style="color:#666600">:=</span> n<span style="color:#666600">.</span>name<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer('</span><span style="color:#666600">||</span>counter<span style="color:#666600">||</span><span style="color:#008800">'):'</span><span style="color:#666600">||</span>name_lis t<span style="color:#666600">(</span>counter<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal  

PL/SQL procedure successfully completed
</span>

Nested Tables

nested table is like a one-dimensional array with an arbitrary number of elements. However, a nested table differs from an array in the following aspects −

  • An array has a declared number of elements, but a nested table does not. The size of a nested table can increase dynamically.

  • An array is always dense, i.e., it always has consecutive subscripts. A nested array is dense initially, but it can become sparse when elements are deleted from it.

A nested table is created using the following syntax −

<span style="color:#313131">TYPE type_name IS TABLE OF element_type [NOT NULL]; 
 
table_name type_name; 
</span>

This declaration is similar to the declaration of an index-by table, but there is no INDEX BY clause.

A nested table can be stored in a database column. It can further be used for simplifying SQL operations where you join a single-column table with a larger table. An associative array cannot be stored in the database.

Example

The following examples illustrate the use of nested table −

<span style="color:#313131">DECLARE 
   TYPE names_table IS TABLE OF VARCHAR2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">);</span> 
   TYPE grades IS TABLE OF INTEGER<span style="color:#666600">;</span>  
   names names_table<span style="color:#666600">;</span> 
   marks grades<span style="color:#666600">;</span> 
   total integer<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   names <span style="color:#666600">:=</span> names_table<span style="color:#666600">(</span><span style="color:#008800">'Kavita'</span><span style="color:#666600">,</span> <span style="color:#008800">'Pritam'</span><span style="color:#666600">,</span> <span style="color:#008800">'Ayan'</span><span style="color:#666600">,</span> <span style="color:#008800">'Rishav'</span><span style="color:#666600">,</span> <span style="color:#008800">'Aziz'</span><span style="color:#666600">);</span> 
   marks<span style="color:#666600">:=</span> grades<span style="color:#666600">(</span><span style="color:#006666">98</span><span style="color:#666600">,</span> <span style="color:#006666">97</span><span style="color:#666600">,</span> <span style="color:#006666">78</span><span style="color:#666600">,</span> <span style="color:#006666">87</span><span style="color:#666600">,</span> <span style="color:#006666">92</span><span style="color:#666600">);</span> 
   total <span style="color:#666600">:=</span> names<span style="color:#666600">.</span>count<span style="color:#666600">;</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Total '</span><span style="color:#666600">||</span> total <span style="color:#666600">||</span> <span style="color:#008800">' Students'</span><span style="color:#666600">);</span> 
   FOR i IN <span style="color:#006666">1</span> <span style="color:#666600">..</span> total LOOP 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Student:'</span><span style="color:#666600">||</span>names<span style="color:#666600">(</span>i<span style="color:#666600">)||</span><span style="color:#008800">', Marks:'</span> <span style="color:#666600">||</span> marks<span style="color:#666600">(</span>i<span style="color:#666600">));</span> 
   <span style="color:#000088">end</span> loop<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Total 5 Students 
Student:Kavita, Marks:98 
Student:Pritam, Marks:97 
Student:Ayan, Marks:78 
Student:Rishav, Marks:87 
Student:Aziz, Marks:92  

PL/SQL procedure successfully completed. 
</span>

Example

Elements of a nested table can also be a %ROWTYPE of any database table or %TYPE of any database table field. The following example illustrates the concept. We will use the CUSTOMERS table stored in our database as −

<span style="color:#313131">Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+ 
</span>

 

<span style="color:#313131">DECLARE 
   CURSOR c_customers <span style="color:#000088">is</span>  
      SELECT  name FROM customers<span style="color:#666600">;</span>  
   TYPE c_list IS TABLE of customerS<span style="color:#666600">.</span><span style="color:#7f0055">No</span><span style="color:#666600">.</span>ame<span style="color:#666600">%</span>type<span style="color:#666600">;</span> 
   name_list c_list <span style="color:#666600">:=</span> c_list<span style="color:#666600">();</span> 
   counter integer <span style="color:#666600">:=</span><span style="color:#006666">0</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   FOR n IN c_customers LOOP 
      counter <span style="color:#666600">:=</span> counter <span style="color:#666600">+</span><span style="color:#006666">1</span><span style="color:#666600">;</span> 
      name_list<span style="color:#666600">.</span>extend<span style="color:#666600">;</span> 
      name_list<span style="color:#666600">(</span>counter<span style="color:#666600">)</span>  <span style="color:#666600">:=</span> n<span style="color:#666600">.</span>name<span style="color:#666600">;</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Customer('</span><span style="color:#666600">||</span>counter<span style="color:#666600">||</span><span style="color:#008800">'):'</span><span style="color:#666600">||</span>name_list<span style="color:#666600">(</span>counter<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal  

PL/SQL procedure successfully completed. 
</span>

Collection Methods

PL/SQL provides the built-in collection methods that make collections easier to use. The following table lists the methods and their purpose −

S.No Method Name & Purpose
1

EXISTS(n)

Returns TRUE if the nth element in a collection exists; otherwise returns FALSE.

2

COUNT

Returns the number of elements that a collection currently contains.

3

LIMIT

Checks the maximum size of a collection.

4

FIRST

Returns the first (smallest) index numbers in a collection that uses the integer subscripts.

5

LAST

Returns the last (largest) index numbers in a collection that uses the integer subscripts.

6

PRIOR(n)

Returns the index number that precedes index n in a collection.

7

NEXT(n)

Returns the index number that succeeds index n.

8

EXTEND

Appends one null element to a collection.

9

EXTEND(n)

Appends n null elements to a collection.

10

EXTEND(n,i)

Appends n copies of the ith element to a collection.

11

TRIM

Removes one element from the end of a collection.

12

TRIM(n)

Removes n elements from the end of a collection.

13

DELETE

Removes all elements from a collection, setting COUNT to 0.

14

DELETE(n)

Removes the nth element from an associative array with a numeric key or a nested table. If the associative array has a string key, the element corresponding to the key value is deleted. If n is null, DELETE(n) does nothing.

15

DELETE(m,n)

Removes all elements in the range m..n from an associative array or nested table. If m is larger than n or if m or n is null, DELETE(m,n)does nothing.

Collection Exceptions

The following table provides the collection exceptions and when they are raised −

Collection Exception Raised in Situations
COLLECTION_IS_NULL You try to operate on an atomically null collection.
NO_DATA_FOUND A subscript designates an element that was deleted, or a nonexistent element of an associative array.
SUBSCRIPT_BEYOND_COUNT A subscript exceeds the number of elements in a collection.
SUBSCRIPT_OUTSIDE_LIMIT A subscript is outside the allowed range.
VALUE_ERROR A subscript is null or not convertible to the key type. This exception might occur if the key is defined as a PLS_INTEGER range, and the subscript is outside this range.

PL/SQL - Transactions

In this chapter, we will discuss the transactions in PL/SQL. A database transaction is an atomic unit of work that may consist of one or more related SQL statements. It is called atomic because the database modifications brought about by the SQL statements that constitute a transaction can collectively be either committed, i.e., made permanent to the database or rolled back (undone) from the database.

A successfully executed SQL statement and a committed transaction are not same. Even if an SQL statement is executed successfully, unless the transaction containing the statement is committed, it can be rolled back and all changes made by the statement(s) can be undone.

Starting and Ending a Transaction

A transaction has a beginning and an end. A transaction starts when one of the following events take place −

  • The first SQL statement is performed after connecting to the database.

  • At each new SQL statement issued after a transaction is completed.

A transaction ends when one of the following events take place −

  • COMMIT or a ROLLBACK statement is issued.

  • DDL statement, such as CREATE TABLE statement, is issued; because in that case a COMMIT is automatically performed.

  • DCL statement, such as a GRANT statement, is issued; because in that case a COMMIT is automatically performed.

  • User disconnects from the database.

  • User exits from SQL*PLUS by issuing the EXIT command, a COMMIT is automatically performed.

  • SQL*Plus terminates abnormally, a ROLLBACK is automatically performed.

  • DML statement fails; in that case a ROLLBACK is automatically performed for undoing that DML statement.

Committing a Transaction

A transaction is made permanent by issuing the SQL command COMMIT. The general syntax for the COMMIT command is −

<span style="color:#313131">COMMIT;
</span>

For example,

<span style="color:#313131">INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">,</span> <span style="color:#008800">'Ramesh'</span><span style="color:#666600">,</span> <span style="color:#006666">32</span><span style="color:#666600">,</span> <span style="color:#008800">'Ahmedabad'</span><span style="color:#666600">,</span> <span style="color:#006666">2000.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">2</span><span style="color:#666600">,</span> <span style="color:#008800">'Khilan'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Delhi'</span><span style="color:#666600">,</span> <span style="color:#006666">1500.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">,</span> <span style="color:#008800">'kaushik'</span><span style="color:#666600">,</span> <span style="color:#006666">23</span><span style="color:#666600">,</span> <span style="color:#008800">'Kota'</span><span style="color:#666600">,</span> <span style="color:#006666">2000.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">4</span><span style="color:#666600">,</span> <span style="color:#008800">'Chaitali'</span><span style="color:#666600">,</span> <span style="color:#006666">25</span><span style="color:#666600">,</span> <span style="color:#008800">'Mumbai'</span><span style="color:#666600">,</span> <span style="color:#006666">6500.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span> <span style="color:#008800">'Hardik'</span><span style="color:#666600">,</span> <span style="color:#006666">27</span><span style="color:#666600">,</span> <span style="color:#008800">'Bhopal'</span><span style="color:#666600">,</span> <span style="color:#006666">8500.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">6</span><span style="color:#666600">,</span> <span style="color:#008800">'Komal'</span><span style="color:#666600">,</span> <span style="color:#006666">22</span><span style="color:#666600">,</span> <span style="color:#008800">'MP'</span><span style="color:#666600">,</span> <span style="color:#006666">4500.00</span> <span style="color:#666600">);</span> 

COMMIT<span style="color:#666600">;</span></span>

Rolling Back Transactions

Changes made to the database without COMMIT could be undone using the ROLLBACK command.

The general syntax for the ROLLBACK command is −

<span style="color:#313131">ROLLBACK [TO SAVEPOINT < savepoint_name>]; 
</span>

When a transaction is aborted due to some unprecedented situation, like system failure, the entire transaction since a commit is automatically rolled back. If you are not using savepoint, then simply use the following statement to rollback all the changes −

<span style="color:#313131">ROLLBACK;
</span>

Savepoints

Savepoints are sort of markers that help in splitting a long transaction into smaller units by setting some checkpoints. By setting savepoints within a long transaction, you can roll back to a checkpoint if required. This is done by issuing the SAVEPOINT command.

The general syntax for the SAVEPOINT command is −

<span style="color:#313131">SAVEPOINT < savepoint_name >;
</span>

For example

<span style="color:#313131">INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">7</span><span style="color:#666600">,</span> <span style="color:#008800">'Rajnish'</span><span style="color:#666600">,</span> <span style="color:#006666">27</span><span style="color:#666600">,</span> <span style="color:#008800">'HP'</span><span style="color:#666600">,</span> <span style="color:#006666">9500.00</span> <span style="color:#666600">);</span> 

INSERT INTO CUSTOMERS <span style="color:#666600">(</span>ID<span style="color:#666600">,</span>NAME<span style="color:#666600">,</span>AGE<span style="color:#666600">,</span>ADDRESS<span style="color:#666600">,</span>SALARY<span style="color:#666600">)</span> 
VALUES <span style="color:#666600">(</span><span style="color:#006666">8</span><span style="color:#666600">,</span> <span style="color:#008800">'Riddhi'</span><span style="color:#666600">,</span> <span style="color:#006666">21</span><span style="color:#666600">,</span> <span style="color:#008800">'WB'</span><span style="color:#666600">,</span> <span style="color:#006666">4500.00</span> <span style="color:#666600">);</span> 
SAVEPOINT sav1<span style="color:#666600">;</span>
  
UPDATE CUSTOMERS 
SET SALARY <span style="color:#666600">=</span> SALARY <span style="color:#666600">+</span> <span style="color:#006666">1000</span><span style="color:#666600">;</span> 
ROLLBACK TO sav1<span style="color:#666600">;</span>
  
UPDATE CUSTOMERS 
SET SALARY <span style="color:#666600">=</span> SALARY <span style="color:#666600">+</span> <span style="color:#006666">1000</span> 
WHERE ID <span style="color:#666600">=</span> <span style="color:#006666">7</span><span style="color:#666600">;</span> 
UPDATE CUSTOMERS 
SET SALARY <span style="color:#666600">=</span> SALARY <span style="color:#666600">+</span> <span style="color:#006666">1000</span> 
WHERE ID <span style="color:#666600">=</span> <span style="color:#006666">8</span><span style="color:#666600">;</span> 

COMMIT<span style="color:#666600">;</span></span>

ROLLBACK TO sav1 − This statement rolls back all the changes up to the point, where you had marked savepoint sav1.

After that, the new changes that you make will start.

Automatic Transaction Control

To execute a COMMIT automatically whenever an INSERT, UPDATE or DELETE command is executed, you can set the AUTOCOMMIT environment variable as −

<span style="color:#313131">SET AUTOCOMMIT ON; 
</span>

You can turn-off the auto commit mode using the following command −

<span style="color:#313131">SET AUTOCOMMIT OFF;
</span>

PL/SQL - Date & Time

In this chapter, we will discuss the Date and Time in PL/SQL. There are two classes of date and time related data types in PL/SQL −

  • Datetime data types
  • Interval data types

The Datetime data types are −

  • DATE
  • TIMESTAMP
  • TIMESTAMP WITH TIME ZONE
  • TIMESTAMP WITH LOCAL TIME ZONE

The Interval data types are −

  • INTERVAL YEAR TO MONTH
  • INTERVAL DAY TO SECOND

Field Values for Datetime and Interval Data Types

Both datetime and interval data types consist of fields. The values of these fields determine the value of the data type. The following table lists the fields and their possible values for datetimes and intervals.

Field Name Valid Datetime Values Valid Interval Values
YEAR -4712 to 9999 (excluding year 0) Any nonzero integer
MONTH 01 to 12 0 to 11
DAY 01 to 31 (limited by the values of MONTH and YEAR, according to the rules of the calendar for the locale) Any nonzero integer
HOUR 00 to 23 0 to 23
MINUTE 00 to 59 0 to 59
SECOND

00 to 59.9(n), where 9(n) is the precision of time fractional seconds

The 9(n) portion is not applicable for DATE.

0 to 59.9(n), where 9(n) is the precision of interval fractional seconds
TIMEZONE_HOUR

-12 to 14 (range accommodates daylight savings time changes)

Not applicable for DATE or TIMESTAMP.

Not applicable
TIMEZONE_MINUTE

00 to 59

Not applicable for DATE or TIMESTAMP.

Not applicable
TIMEZONE_REGION Not applicable for DATE or TIMESTAMP. Not applicable
TIMEZONE_ABBR Not applicable for DATE or TIMESTAMP. Not applicable

The Datetime Data Types and Functions

Following are the Datetime data types −

DATE

It stores date and time information in both character and number datatypes. It is made of information on century, year, month, date, hour, minute, and second. It is specified as −

TIMESTAMP

It is an extension of the DATE data type. It stores the year, month, and day of the DATE datatype, along with hour, minute, and second values. It is useful for storing precise time values.

TIMESTAMP WITH TIME ZONE

It is a variant of TIMESTAMP that includes a time zone region name or a time zone offset in its value. The time zone offset is the difference (in hours and minutes) between local time and UTC. This data type is useful for collecting and evaluating date information across geographic regions.

TIMESTAMP WITH LOCAL TIME ZONE

It is another variant of TIMESTAMP that includes a time zone offset in its value.

Following table provides the Datetime functions (where, x has the datetime value) −

S.No Function Name & Description
1

ADD_MONTHS(x, y);

Adds y months to x.

2

LAST_DAY(x);

Returns the last day of the month.

3

MONTHS_BETWEEN(x, y);

Returns the number of months between x and y.

4

NEXT_DAY(x, day);

Returns the datetime of the next day after x.

5

NEW_TIME;

Returns the time/day value from a time zone specified by the user.

6

ROUND(x [, unit]);

Rounds x.

7

SYSDATE();

Returns the current datetime.

8

TRUNC(x [, unit]);

Truncates x.

Timestamp functions (where, x has a timestamp value) −

S.No Function Name & Description
1

CURRENT_TIMESTAMP();

Returns a TIMESTAMP WITH TIME ZONE containing the current session time along with the session time zone.

2

EXTRACT({ YEAR | MONTH | DAY | HOUR | MINUTE | SECOND } | { TIMEZONE_HOUR | TIMEZONE_MINUTE } | { TIMEZONE_REGION | } TIMEZONE_ABBR ) FROM x)

Extracts and returns a year, month, day, hour, minute, second, or time zone from x.

3

FROM_TZ(x, time_zone);

Converts the TIMESTAMP x and the time zone specified by time_zone to a TIMESTAMP WITH TIMEZONE.

4

LOCALTIMESTAMP();

Returns a TIMESTAMP containing the local time in the session time zone.

5

SYSTIMESTAMP();

Returns a TIMESTAMP WITH TIME ZONE containing the current database time along with the database time zone.

6

SYS_EXTRACT_UTC(x);

Converts the TIMESTAMP WITH TIMEZONE x to a TIMESTAMP containing the date and time in UTC.

7

TO_TIMESTAMP(x, [format]);

Converts the string x to a TIMESTAMP.

8

TO_TIMESTAMP_TZ(x, [format]);

Converts the string x to a TIMESTAMP WITH TIMEZONE.

Examples

The following code snippets illustrate the use of the above functions −

Example 1

<span style="color:#313131">SELECT SYSDATE FROM DUAL<span style="color:#666600">;</span> </span>

Output −

<span style="color:#313131">08/31/2012 5:25:34 PM 
</span>

Example 2

<span style="color:#313131">SELECT TO_CHAR<span style="color:#666600">(</span>CURRENT_DATE<span style="color:#666600">,</span> <span style="color:#008800">'DD-MM-YYYY HH:MI:SS'</span><span style="color:#666600">)</span> FROM DUAL<span style="color:#666600">;</span> </span>

Output −

<span style="color:#313131">31-08-2012 05:26:14
</span>

Example 3

<span style="color:#313131">SELECT ADD_MONTHS<span style="color:#666600">(</span>SYSDATE<span style="color:#666600">,</span> <span style="color:#006666">5</span><span style="color:#666600">)</span> FROM DUAL<span style="color:#666600">;</span></span>

Output −

<span style="color:#313131">01/31/2013 5:26:31 PM 
</span>

Example 4

<span style="color:#313131">SELECT LOCALTIMESTAMP FROM DUAL<span style="color:#666600">;</span> </span>

Output −

<span style="color:#313131">8/31/2012 5:26:55.347000 PM 
</span>

The Interval Data Types and Functions

Following are the Interval data types −

  • IINTERVAL YEAR TO MONTH − It stores a period of time using the YEAR and MONTH datetime fields.

  • INTERVAL DAY TO SECOND − It stores a period of time in terms of days, hours, minutes, and seconds.

Interval Functions

S.No Function Name & Description
1

NUMTODSINTERVAL(x, interval_unit);

Converts the number x to an INTERVAL DAY TO SECOND.

2

NUMTOYMINTERVAL(x, interval_unit);

Converts the number x to an INTERVAL YEAR TO MONTH.

3

TO_DSINTERVAL(x);

Converts the string x to an INTERVAL DAY TO SECOND.

4

TO_YMINTERVAL(x);

Converts the string x to an INTERVAL YEAR TO MONTH.

PL/SQL - DBMS Output

In this chapter, we will discuss the DBMS Output in PL/SQL. The DBMS_OUTPUT is a built-in package that enables you to display output, debugging information, and send messages from PL/SQL blocks, subprograms, packages, and triggers. We have already used this package throughout our tutorial.

Let us look at a small code snippet that will display all the user tables in the database. Try it in your database to list down all the table names −

<span style="color:#313131"><span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line  <span style="color:#666600">(</span>user <span style="color:#666600">||</span> <span style="color:#008800">' Tables in the database:'</span><span style="color:#666600">);</span> 
   FOR t IN <span style="color:#666600">(</span>SELECT table_name FROM user_tables<span style="color:#666600">)</span> 
   LOOP 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>t<span style="color:#666600">.</span>table_name<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

DBMS_OUTPUT Subprograms

The DBMS_OUTPUT package has the following subprograms −

S.No Subprogram & Purpose
1

DBMS_OUTPUT.DISABLE;

Disables message output.

2

DBMS_OUTPUT.ENABLE(buffer_size IN INTEGER DEFAULT 20000);

Enables message output. A NULL value of buffer_size represents unlimited buffer size.

 
3

DBMS_OUTPUT.GET_LINE (line OUT VARCHAR2, status OUT INTEGER);

Retrieves a single line of buffered information.

4

DBMS_OUTPUT.GET_LINES (lines OUT CHARARR, numlines IN OUT INTEGER);

Retrieves an array of lines from the buffer.

5

DBMS_OUTPUT.NEW_LINE;

Puts an end-of-line marker.

6

DBMS_OUTPUT.PUT(item IN VARCHAR2);

Places a partial line in the buffer.

7

DBMS_OUTPUT.PUT_LINE(item IN VARCHAR2);

Places a line in the buffer.

Example

<span style="color:#313131">DECLARE 
   lines dbms_output<span style="color:#666600">.</span>chararr<span style="color:#666600">;</span> 
   num_lines number<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   <span style="color:#666600">--</span> enable the buffer <span style="color:#000088">with</span> <span style="color:#000088">default</span> size <span style="color:#006666">20000</span> 
   dbms_output<span style="color:#666600">.</span>enable<span style="color:#666600">;</span> 
   
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Hello Reader!'</span><span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Hope you have enjoyed the tutorials!'</span><span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Have a great time exploring pl/sql!'</span><span style="color:#666600">);</span> 
  
   num_lines <span style="color:#666600">:=</span> <span style="color:#006666">3</span><span style="color:#666600">;</span> 
  
   dbms_output<span style="color:#666600">.</span>get_lines<span style="color:#666600">(</span>lines<span style="color:#666600">,</span> num_lines<span style="color:#666600">);</span> 
  
   FOR i IN <span style="color:#006666">1.</span><span style="color:#666600">.</span>num_lines LOOP 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span>lines<span style="color:#666600">(</span>i<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> LOOP<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span>  </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Hello Reader! 
Hope you have enjoyed the tutorials! 
Have a great time exploring pl/sql!  

PL/SQL procedure successfully completed.
</span>

PL/SQL - Object Oriented

In this chapter, we will discuss Object-Oriented PL/SQL. PL/SQL allows defining an object type, which helps in designing object-oriented database in Oracle. An object type allows you to create composite types. Using objects allow you to implement real world objects with specific structure of data and methods for operating it. Objects have attributes and methods. Attributes are properties of an object and are used for storing an object's state; and methods are used for modeling its behavior.

Objects are created using the CREATE [OR REPLACE] TYPE statement. Following is an example to create a simple address object consisting of few attributes −

<span style="color:#313131">CREATE OR REPLACE TYPE address AS OBJECT 
<span style="color:#666600">(</span>house_no varchar2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">),</span> 
 street varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">),</span> 
 city varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">),</span> 
 state varchar2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">),</span> 
 pincode varchar2<span style="color:#666600">(</span><span style="color:#006666">10</span><span style="color:#666600">)</span> 
<span style="color:#666600">);</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Type created. 
</span>

Let's create one more object customer where we will wrap attributes and methods together to have object-oriented feeling −

<span style="color:#313131">CREATE OR REPLACE TYPE customer AS OBJECT 
<span style="color:#666600">(</span>code number<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">),</span> 
 name varchar2<span style="color:#666600">(</span><span style="color:#006666">30</span><span style="color:#666600">),</span> 
 contact_no varchar2<span style="color:#666600">(</span><span style="color:#006666">12</span><span style="color:#666600">),</span> 
 addr address<span style="color:#666600">,</span> 
 member procedure display 
<span style="color:#666600">);</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Type created.
</span>

Instantiating an Object

Defining an object type provides a blueprint for the object. To use this object, you need to create instances of this object. You can access the attributes and methods of the object using the instance name and the access operator (.)as follows −

<span style="color:#313131">DECLARE 
   residence address<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   residence <span style="color:#666600">:=</span> address<span style="color:#666600">(</span><span style="color:#008800">'103A'</span><span style="color:#666600">,</span> <span style="color:#008800">'M.G.Road'</span><span style="color:#666600">,</span> <span style="color:#008800">'Jaipur'</span><span style="color:#666600">,</span> <span style="color:#008800">'Rajasthan'</span><span style="color:#666600">,</span><span style="color:#008800">'201301'</span><span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'House No: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>house_no<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Street: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>street<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'City: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>city<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'State: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>state<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Pincode: '</span><span style="color:#666600">||</span> residence<span style="color:#666600">.</span>pincode<span style="color:#666600">);</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">House No: 103A 
Street: M.G.Road 
City: Jaipur 
State: Rajasthan 
Pincode: 201301  

PL/SQL procedure successfully completed. 
</span>

Member Methods

Member methods are used for manipulating the attributes of the object. You provide the declaration of a member method while declaring the object type. The object body defines the code for the member methods. The object body is created using the CREATE TYPE BODY statement.

Constructors are functions that return a new object as its value. Every object has a system defined constructor method. The name of the constructor is same as the object type. For example −

<span style="color:#313131">residence <span style="color:#666600">:=</span> address<span style="color:#666600">(</span><span style="color:#008800">'103A'</span><span style="color:#666600">,</span> <span style="color:#008800">'M.G.Road'</span><span style="color:#666600">,</span> <span style="color:#008800">'Jaipur'</span><span style="color:#666600">,</span> <span style="color:#008800">'Rajasthan'</span><span style="color:#666600">,</span><span style="color:#008800">'201301'</span><span style="color:#666600">);</span> </span>

The comparison methods are used for comparing objects. There are two ways to compare objects −

Map method

The Map method is a function implemented in such a way that its value depends upon the value of the attributes. For example, for a customer object, if the customer code is same for two customers, both customers could be the same. So the relationship between these two objects would depend upon the value of code.

Order method

The Order method implements some internal logic for comparing two objects. For example, for a rectangle object, a rectangle is bigger than another rectangle if both its sides are bigger.

Using Map method

Let us try to understand the above concepts using the following rectangle object −

<span style="color:#313131">CREATE OR REPLACE TYPE rectangle AS OBJECT 
<span style="color:#666600">(</span>length number<span style="color:#666600">,</span> 
 width number<span style="color:#666600">,</span> 
 member <span style="color:#000088">function</span> enlarge<span style="color:#666600">(</span> inc number<span style="color:#666600">)</span> <span style="color:#000088">return</span> rectangle<span style="color:#666600">,</span> 
 member procedure display<span style="color:#666600">,</span> 
 map member <span style="color:#000088">function</span> measure <span style="color:#000088">return</span> number 
<span style="color:#666600">);</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Type created.
</span>

Creating the type body −

<span style="color:#313131">CREATE OR REPLACE TYPE BODY rectangle AS 
   MEMBER FUNCTION enlarge<span style="color:#666600">(</span>inc number<span style="color:#666600">)</span> <span style="color:#000088">return</span> rectangle IS 
   <span style="color:#000088">BEGIN</span> 
      <span style="color:#000088">return</span> rectangle<span style="color:#666600">(</span><span style="color:#000088">self</span><span style="color:#666600">.</span>length <span style="color:#666600">+</span> inc<span style="color:#666600">,</span> <span style="color:#000088">self</span><span style="color:#666600">.</span>width <span style="color:#666600">+</span> inc<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> enlarge<span style="color:#666600">;</span>  
   MEMBER PROCEDURE display IS 
   <span style="color:#000088">BEGIN</span>  
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Length: '</span><span style="color:#666600">||</span> length<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Width: '</span><span style="color:#666600">||</span> width<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> display<span style="color:#666600">;</span>  
   MAP MEMBER FUNCTION measure <span style="color:#000088">return</span> number IS 
   <span style="color:#000088">BEGIN</span> 
      <span style="color:#000088">return</span> <span style="color:#666600">(</span>sqrt<span style="color:#666600">(</span>length<span style="color:#666600">*</span>length <span style="color:#666600">+</span> width<span style="color:#666600">*</span>width<span style="color:#666600">));</span> 
   <span style="color:#000088">END</span> measure<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Type body created.
</span>

Now using the rectangle object and its member functions −

<span style="color:#313131">DECLARE 
   r1 rectangle<span style="color:#666600">;</span> 
   r2 rectangle<span style="color:#666600">;</span> 
   r3 rectangle<span style="color:#666600">;</span> 
   inc_factor number <span style="color:#666600">:=</span> <span style="color:#006666">5</span><span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   r1 <span style="color:#666600">:=</span> rectangle<span style="color:#666600">(</span><span style="color:#006666">3</span><span style="color:#666600">,</span> <span style="color:#006666">4</span><span style="color:#666600">);</span> 
   r2 <span style="color:#666600">:=</span> rectangle<span style="color:#666600">(</span><span style="color:#006666">5</span><span style="color:#666600">,</span> <span style="color:#006666">7</span><span style="color:#666600">);</span> 
   r3 <span style="color:#666600">:=</span> r1<span style="color:#666600">.</span>enlarge<span style="color:#666600">(</span>inc_factor<span style="color:#666600">);</span> 
   r3<span style="color:#666600">.</span>display<span style="color:#666600">;</span>  
   IF <span style="color:#666600">(</span>r1 <span style="color:#666600">></span> r2<span style="color:#666600">)</span> THEN <span style="color:#666600">--</span> calling measure <span style="color:#000088">function</span> 
      r1<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   ELSE 
      r2<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Length: 8 
Width: 9 
Length: 5 
Width: 7  

PL/SQL procedure successfully completed. 
</span>

Using Order method

Now, the same effect could be achieved using an order method. Let us recreate the rectangle object using an order method −

<span style="color:#313131">CREATE OR REPLACE TYPE rectangle AS OBJECT 
<span style="color:#666600">(</span>length number<span style="color:#666600">,</span> 
 width number<span style="color:#666600">,</span> 
 member procedure display<span style="color:#666600">,</span> 
 order member <span style="color:#000088">function</span> measure<span style="color:#666600">(</span>r rectangle<span style="color:#666600">)</span> <span style="color:#000088">return</span> number 
<span style="color:#666600">);</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Type created.
</span>

Creating the type body −

<span style="color:#313131">CREATE OR REPLACE TYPE BODY rectangle AS 
   MEMBER PROCEDURE display IS 
   <span style="color:#000088">BEGIN</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Length: '</span><span style="color:#666600">||</span> length<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Width: '</span><span style="color:#666600">||</span> width<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> display<span style="color:#666600">;</span>  
   ORDER MEMBER FUNCTION measure<span style="color:#666600">(</span>r rectangle<span style="color:#666600">)</span> <span style="color:#000088">return</span> number IS 
   <span style="color:#000088">BEGIN</span> 
      IF<span style="color:#666600">(</span>sqrt<span style="color:#666600">(</span><span style="color:#000088">self</span><span style="color:#666600">.</span>length<span style="color:#666600">*</span><span style="color:#000088">self</span><span style="color:#666600">.</span>length <span style="color:#666600">+</span> <span style="color:#000088">self</span><span style="color:#666600">.</span>width<span style="color:#666600">*</span><span style="color:#000088">self</span><span style="color:#666600">.</span>width<span style="color:#666600">)></span> 
         sqrt<span style="color:#666600">(</span>r<span style="color:#666600">.</span>length<span style="color:#666600">*</span>r<span style="color:#666600">.</span>length <span style="color:#666600">+</span> r<span style="color:#666600">.</span>width<span style="color:#666600">*</span>r<span style="color:#666600">.</span>width<span style="color:#666600">))</span> <span style="color:#000088">then</span> 
         <span style="color:#000088">return</span><span style="color:#666600">(</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
      ELSE 
         <span style="color:#000088">return</span><span style="color:#666600">(-</span><span style="color:#006666">1</span><span style="color:#666600">);</span> 
      <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> measure<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span> </span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Type body created.
</span>

Using the rectangle object and its member functions −

<span style="color:#313131">DECLARE 
   r1 rectangle<span style="color:#666600">;</span> 
   r2 rectangle<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   r1 <span style="color:#666600">:=</span> rectangle<span style="color:#666600">(</span><span style="color:#006666">23</span><span style="color:#666600">,</span> <span style="color:#006666">44</span><span style="color:#666600">);</span> 
   r2 <span style="color:#666600">:=</span> rectangle<span style="color:#666600">(</span><span style="color:#006666">15</span><span style="color:#666600">,</span> <span style="color:#006666">17</span><span style="color:#666600">);</span> 
   r1<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   r2<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   IF <span style="color:#666600">(</span>r1 <span style="color:#666600">></span> r2<span style="color:#666600">)</span> THEN <span style="color:#666600">--</span> calling measure <span style="color:#000088">function</span> 
      r1<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   ELSE 
      r2<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   <span style="color:#000088">END</span> IF<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131"><span style="color:#7f0055">Length</span><span style="color:#666600">:</span> <span style="color:#006666">23</span> 
<span style="color:#7f0055">Width</span><span style="color:#666600">:</span> <span style="color:#006666">44</span> 
<span style="color:#7f0055">Length</span><span style="color:#666600">:</span> <span style="color:#006666">15</span> 
<span style="color:#7f0055">Width</span><span style="color:#666600">:</span> <span style="color:#006666">17</span> 
<span style="color:#7f0055">Length</span><span style="color:#666600">:</span> <span style="color:#006666">23</span> 
<span style="color:#7f0055">Width</span><span style="color:#666600">:</span> <span style="color:#006666">44</span> 

PL<span style="color:#666600">/</span>SQL procedure successfully completed<span style="color:#666600">.</span></span>

Inheritance for PL/SQL Objects

PL/SQL allows creating object from the existing base objects. To implement inheritance, the base objects should be declared as NOT FINAL. The default is FINAL.

The following programs illustrate the inheritance in PL/SQL Objects. Let us create another object named TableTop, this is inherited from the Rectangle object. For this, we need to create the base rectangle object −

<span style="color:#313131">CREATE OR REPLACE TYPE rectangle AS OBJECT 
<span style="color:#666600">(</span>length number<span style="color:#666600">,</span> 
 width number<span style="color:#666600">,</span> 
 member <span style="color:#000088">function</span> enlarge<span style="color:#666600">(</span> inc number<span style="color:#666600">)</span> <span style="color:#000088">return</span> rectangle<span style="color:#666600">,</span> 
 NOT FINAL member procedure display<span style="color:#666600">)</span> NOT FINAL 
<span style="color:#666600">/</span></span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Type created.
</span>

Creating the base type body −

<span style="color:#313131">CREATE OR REPLACE TYPE BODY rectangle AS 
   MEMBER FUNCTION enlarge<span style="color:#666600">(</span>inc number<span style="color:#666600">)</span> <span style="color:#000088">return</span> rectangle IS 
   <span style="color:#000088">BEGIN</span> 
      <span style="color:#000088">return</span> rectangle<span style="color:#666600">(</span><span style="color:#000088">self</span><span style="color:#666600">.</span>length <span style="color:#666600">+</span> inc<span style="color:#666600">,</span> <span style="color:#000088">self</span><span style="color:#666600">.</span>width <span style="color:#666600">+</span> inc<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> enlarge<span style="color:#666600">;</span>  
   MEMBER PROCEDURE display IS 
   <span style="color:#000088">BEGIN</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Length: '</span><span style="color:#666600">||</span> length<span style="color:#666600">);</span> 
      dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Width: '</span><span style="color:#666600">||</span> width<span style="color:#666600">);</span> 
   <span style="color:#000088">END</span> display<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

When the above code is executed at the SQL prompt, it produces the following result −

<span style="color:#313131">Type body created.
</span>

创建子对象桌面 -

<span style="color:#313131">CREATE OR REPLACE TYPE tabletop UNDER rectangle 
<span style="color:#666600">(</span>   
   material varchar2<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">),</span> 
   OVERRIDING member procedure display 
<span style="color:#666600">)</span> 
<span style="color:#666600">/</span> </span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type created.
</span>

为子对象桌面创建类型主体

<span style="color:#313131">CREATE OR REPLACE TYPE BODY tabletop AS 
OVERRIDING MEMBER PROCEDURE display IS 
<span style="color:#000088">BEGIN</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Length: '</span><span style="color:#666600">||</span> length<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Width: '</span><span style="color:#666600">||</span> width<span style="color:#666600">);</span> 
   dbms_output<span style="color:#666600">.</span>put_line<span style="color:#666600">(</span><span style="color:#008800">'Material: '</span><span style="color:#666600">||</span> material<span style="color:#666600">);</span> 
<span style="color:#000088">END</span> display<span style="color:#666600">;</span> 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type body created.
</span>

使用桌面对象及其成员函数 -

<span style="color:#313131">DECLARE 
   t1 tabletop<span style="color:#666600">;</span> 
   t2 tabletop<span style="color:#666600">;</span> 
<span style="color:#000088">BEGIN</span> 
   t1<span style="color:#666600">:=</span> tabletop<span style="color:#666600">(</span><span style="color:#006666">20</span><span style="color:#666600">,</span> <span style="color:#006666">10</span><span style="color:#666600">,</span> <span style="color:#008800">'Wood'</span><span style="color:#666600">);</span> 
   t2 <span style="color:#666600">:=</span> tabletop<span style="color:#666600">(</span><span style="color:#006666">50</span><span style="color:#666600">,</span> <span style="color:#006666">30</span><span style="color:#666600">,</span> <span style="color:#008800">'Steel'</span><span style="color:#666600">);</span> 
   t1<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
   t2<span style="color:#666600">.</span>display<span style="color:#666600">;</span> 
<span style="color:#000088">END</span><span style="color:#666600">;</span>
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Length: 20 
Width: 10 
Material: Wood 
Length: 50 
Width: 30 
Material: Steel  

PL/SQL procedure successfully completed. 
</span>

PL / SQL中的抽象对象

不实例化子句允许你声明一个抽象的对象。您不能使用抽象对象; 您必须创建此类对象的子类型或子类型才能使用其功能。

例如,

<span style="color:#313131">CREATE OR REPLACE TYPE rectangle AS OBJECT 
<span style="color:#666600">(</span>length number<span style="color:#666600">,</span> 
 width number<span style="color:#666600">,</span> 
 NOT INSTANTIABLE NOT FINAL MEMBER PROCEDURE display<span style="color:#666600">)</span>  
 NOT INSTANTIABLE NOT FINAL 
<span style="color:#666600">/</span></span>

当在SQL提示符下执行上述代码时,它会产生以下结果 -

<span style="color:#313131">Type created.
</span>

教程转载翻译自:https://www.tutorialspoint.com/plsql/plsql_useful_resources.htm