Oracle PL/SQL Programming 第7章:Working with Program Data 读书笔记

总的目录和进度,请参见开始读 Oracle PL/SQL Programming 第6版

几乎您编写的每个 PL/SQL 块都会定义和操作程序数据。 程序数据由仅存在于 PL/SQL 会话中的数据结构组成(物理上,在会话的程序全局区域或 PGA 中); 它们不存储在数据库中。 程序数据可以是:

  • 变量或常数
    变量的值在程序执行期间可能会发生变化。 一旦在声明时设置,常量的值就是静态的。

  • 标量或复合
    标量由单个值组成,例如数字或字符串。 复合数据由多个值组成,例如记录、集合或对象类型实例。

  • 容器化
    容器可能包含从数据库获取的信息,或者数据库中从未存在且可能永远不会出现的数据。

在使用 PL/SQL 代码中的程序数据之前,必须声明数据结构,并为其指定名称和数据类型。

本章介绍如何声明程序数据。 它涵盖了管理数据结构名称格式的规则。 它提供了 PL/SQL 支持的所有不同类型数据的快速参考,并探讨了数据类型转换的概念。 本章最后给出了一些处理程序数据的建议。 本书这一部分的其余章节描述了程序数据的特定类型。

Naming Your Program Data

要使用变量或常量,您必须首先声明并给它一个名称。
名称必须以字母开头,最长 30 个字符。名称不区分大小写(除非放在双引号内,但不建议使用)。

以下是命名变量、常量和类型的两个重要建议:

  • 确保每个名称准确反映其用法并且一目了然

  • 建立一致、合理的命名约定
    此类约定通常涉及使用前缀和/或后缀来指示类型和用法。 例如,局部变量应以“l_”为前缀,而包中定义的全局变量应以“g_”为前缀。 所有记录类型都应具有后缀“_rt”,依此类推。 作者的书《Oracle PL/SQL 最佳实践》中的示例代码提供了一套全面的命名约定可供下载。

Overview of PL/SQL Datatypes

声明变量或常量时,必须为其分配数据类型。 总体而言,PL/SQL 是一种“静态类型编程语言”(类型检查是在编译时而不是运行时执行,如C语言;动态类型编程语言包括Perl,JavaScript,Ruby)。静态类型可以在编译时发现类型错误,这可以增加程序的可靠性并使其执行速度更快。动态类型的好处是更容易实现metaclasses 和introspection。

PL/SQL 在STANDARD 包中提供了一套全面的预定义标量和复合数据类型,您可以创建用户定义类型(也称为抽象数据类型)。 一些类型如 Boolean 和 NATURAL并不能为数据库列定义所用。

Character Data

定长字符串(CHAR 和 NCHAR)和变长字符串(VARCHAR2 和 NVARCHAR2)类型。
字符大对象(CLOB和NCLOB)。LONG不建议用,只是为了向后兼容。

Numbers

NUMBER类型最常用,可用于十进制定点和浮点值以及整数。

二进制浮点类型:BINARY_FLOAT 和 BINARY_DOUBLE。具有二进制精度,不是十进制,因此可能有舍入,因此不能用于钱的表示。

SIMPLE_FLOAT and SIMPLE_DOUBLE类似于以上两类型,但它们不允许 NULL 值,也不会在发生溢出时引发异常。

PLS_INTEGER 是一种整数类型,其运算在硬件中实现。 FOR 循环计数器被实现为 PLS_INTEGER。 SIMPLE_INTEGER 与 PLS_INTEGER 具有相同的值范围,但它不允许 NULL 值,发生溢出时也不会引发异常。

Dates, Timestamps, and Intervals

DATE(日期和时间,时间精确到秒),INTERVAL和TIMESTAMP。

Booleans

BOOLEAN,三值逻辑,取值为 TRUE, FALSE和NULL之一。

布尔数据库类型直到23c才支持。之前可以用约束实现:

flag char(1) check (flag in ( 'Y', 'N' )),

Binary Data

RAW(无字符集转换), BLOB和BFILE(存储在数据库外),用于非结构化数据。

ROWID

ROWID 和 UROWID,用于表示表中行的地址。 ROWID 表示行在其表中的唯一物理地址; UROWID 表示索引组织表 (IOT) 中行的逻辑位置。 ROWID也是一个SQL伪列,可以包含在SQL语句中。

REF CURSORs

REF CURSOR 数据类型声明游标变量。 游标变量可以与静态或动态 SQL 语句一起使用,以实现更灵活的程序。 REF CURSOR 有两种形式:强 REF CURSOR 和弱 REF CURSOR。 PL/SQL 是一种静态类型语言,弱 REF CURSOR 是少数受支持的动态类型结构之一。

-- 强 REF CURSORTYPE book_data_t IS REF CURSOR RETURN book%ROWTYPE;
-- 弱 REF CURSOR TYPE book_data_t IS REF CURSOR;book_curs_var_b SYS_REFCURSOR;

Internet Datatypes

XMLType,URIType 和 HttpURIType。

“Any” Datatypes

Any 数据类型主要用于编写更通用的代码,允许您动态封装和访问任何其他 SQL 类型的类型描述、数据实例和数据实例集。 您可以使用这些类型(以及为它们定义的方法,因为它们是对象类型)来执行诸如确定存储在特定嵌套表中的数据类型之类的操作,而无需访问该表类型的实际声明!

Any 数据类型包括 AnyType、AnyData 和 AnyDataSet。

User-Defined Datatypes

您可以使用 Oracle 内置数据类型和其他用户定义的数据类型来创建您自己的任意复杂类型,以模拟系统中数据的结构和行为。

Declaring Program Data

除了少数例外,您必须在使用变量和常量之前声明它们。 这些声明位于 PL/SQL 程序的声明部分。 声明可以包括变量、常量、类型(例如集合类型或记录类型)和异常。

Declaring a Variable

当您声明变量时,PL/SQL 会为变量的值分配内存并命名存储位置,以便可以检索和更改该值。 声明还指定了变量的数据类型; 然后使用该数据类型来验证分配给变量的值。语法为:

name datatype [NOT NULL] [ := | DEFAULT default_assignment];

示例:

-- 错误,非空的变量和常数都必须赋值d1 NUMBER NOT NULL;d1 CONSTANT NUMBER;
-- 正确d1 NUMBER NOT NULL DEFAULT 5;
-- 正确,等同于上一句d2 NUMBER NOT NULL := 5;

作者建议对于常数使用赋值(:=),对于变量使用DEFAULT。这样代码易理解。
例如:

d1 CONSTANT NUMBER := 5;
d2 NUMBER DEFAULT 5;

Declaring Constants

在数据类型前加CONSTANT关键字即可,后续不允许改。

未命名常量是literal,例如 2 或“Bobby McGee”。 literal虽然没有名称,但它确实有隐含的(未声明的)数据类型。

The NOT NULL Clause

下面这个例子不错,会报错:

declared1 NUMBER NOT NULL := 5;
begind1 := NULL;
end;
/

Anchored Declarations

明确的指定数据类型,称为硬编码数据类型;锚定数据类型指将变量的数据类型设置为已定义的数据结构的数据类型:另一个 PL/SQL 变量、预定义的 TYPE 或 SUBTYPE、数据库表或数据库中表的特定列。

锚定又分为标量锚定和记录锚定:

-- 硬编码数据类型
a varchar2(100);
-- 锚定数据类型之标量锚定
b a%TYPE;
b employees.emp_id%TYPE;

锚定引用在编译代码时解析。如果这些元素发生更改,则发生锚定的代码将被标记为无效。

锚定声明很好地说明了:PL/SQL 不仅仅是一种过程式编程语言,而且是专门为 Oracle SQL 语言的扩展而设计的。

Anchoring to Cursors and Tables

-- 锚定数据类型之记录锚定
a employees%ROWTYPE;-- 显式记录锚定
CURSOR emp_cur ISSELECT emp_id, emp_name FROM employeesWHERE  emp_id = 100;
l_emp_rec emp_cur%ROWTYPE;-- 隐式记录锚定
for l_emp_rec in (SELECT emp_id, emp_name FROM employees WHERE  emp_id = 100;)
...

Benefits of Anchored Declarations

锚定好处包括:

  • 与数据库列同步(保持一致)
  • 局部变量定义的范式化(但业务需求变化时,可以很容易的一次性改动)

Anchoring to NOT NULL Datatypes

使用锚定时,数据库表中的 NOT NULL 约束不会自动传输到变量。而NOT NULL 变量则会传输。

Programmer-Defined Subtypes

也称为抽象数据类型。有约束和非约束两类。

-- 约束
SUBTYPE POSITIVE IS BINARY_INTEGER RANGE 1 .. 2147483647;-- 非约束
SUBTYPE FLOAT IS NUMBER;

非约束相当于别名。注意,锚定到数据库列的子类型不会将 NOT NULL 约束传递给它定义的变量。 它也不传输原始声明中包含的默认值。

Conversion Between Datatypes

数据类型转换分为隐式和显式两种。

Implicit Data Conversion

建议隐式,可能会带来安全问题,代码可读性问题等。

隐式转换可能会产生异常,同时并非所有的类型都可以隐式转换。

隐式转换的坏处包括:

  • PL/SQL 通常是一种静态类型语言。 当您的程序执行隐式转换时,您会失去静态类型的一些好处,例如代码的清晰度和安全性。
  • 每个隐式转换都代表着您对程序的控制权的损失,您的代码可能受到影响。
  • PL/SQL 执行的隐式转换取决于代码执行的上下文。 PL/SQL 执行的转换不一定是您所期望的转换。
  • 显式转换使代码更易于阅读和理解,也可以消除潜在的误解。

可参考文章On Implicit Conversions and More,以及 How Can I Find The Implicit Conversion (Doc ID 423181.1)。

Explicit Datatype Conversion

Oracle 提供了一套全面的转换函数和运算符可在 SQL 和 PL/SQL 中使用,以下为主要的内置转换函数:

名字描述
ASCIISTR将任何字符集中的字符串转换为数据库字符集中的 ASCII 字符串
CAST将一种内置数据类型或集合类型值转换为另一种内置数据类型或集合类型值; 这种非常强大的转换机制可以用作 TO_DATE 等传统函数的替代品。
CHARTOROWID将字符串转换为 ROWID。
CONVERT将字符串从一种字符集转换为另一种字符集。
FROM_TZ将时区信息添加到 TIMESTAMP 值,从而将其转换为 TIMESTAMP WITH TIME ZONE 值。
HEXTORAW从十六进制转换为原始格式。
MULTISET将数据库表映射到集合。
NUMTODSINTERVAL将数字(或数值表达式)转换为 INTERVAL DAY TO SECOND 文字。
NUMTOYMINTERVAL将数字(或数值表达式)转换为 INTERVAL YEAR TO MONTH 文字。
RAWTOHEX, RAWTONHEX从原始值转换为十六进制。
REFTOHEX将 REF 值转换为包含 REF 值的十六进制表示形式的字符串。
ROWIDTOCHAR, ROWIDTONCHAR将二进制 ROWID 值转换为字符串。
TABLE将集合映射到数据库表; 这是 MULTISET 的逆过程。
THE将单行中的单列值映射到虚拟数据库表中。
TO_BINARY_DOUBLE将数字或字符串转换为 BINARY_DOUBLE。
TO_BINARY_FLOAT将数字或字符串转换为 BINARY_FLOAT。
TO_BLOB从 RAW 值转换为 BLOB。
TO_CHAR、TO_NCHAR(字符版本)在数据库字符集和国家字符集之间转换字符数据。
TO_CHAR、TO_NCHAR(日期版本)将日期转换为字符串。
TO_CHAR、TO_NCHAR(数字版本)将数字转换为字符串(分别为 VARCHAR2 或 NVARCHAR2)。
TO_CLOB、TO_NCLOB从 VARCHAR2、NVARCHAR2 或 NCLOB 值转换为 CLOB(或 NCLOB)。
TO_DATE将字符串转换为日期。
TO_DSINTERVAL将 CHAR、VARCHAR2、NCHAR 或 NVARCHAR2 数据类型的字符串转换为 INTERVAL DAY TO SECOND 类型。
TO_LOB从 LONG 转换为 LOB。
TO_MULTI_BYTE如果可能,将输入字符串中的单字节字符转换为其多字节等效项。
TO_NUMBER将字符串或数字(例如 BINARY_FLOAT)转换为 NUMBER。
TO_RAW从 BLOB 转换为 RAW。
TO_SINGLE_BYTE将输入字符串中的多字节字符转换为其相应的单字节字符。
TO_TIMESTAMP将字符串转换为 TIMESTAMP 类型的值。
TO_TIMESTAMP_TZ将字符串转换为 TO_TIMESTAMP_TZ 类型的值。
TO_YMINTERVAL将 CHAR、VARCHAR2、NCHAR 或 NVARCHAR2 数据类型的字符串转换为 INTERVAL YEAR TO MONTH 类型。
TRANSLATE … USING将提供的文本转换为为数据库字符集和国家字符集之间的转换指定的字符集。
UNISTR将任意字符集中的字符串作为参数,并以数据库 Unicode 字符集中的 Unicode 形式返回。
The CHARTOROWID function

输入字符串格式必须为OOOOOFFFBBBBBBRRR。其中:

  • OOOOO 是数据对象编号
  • FFF 是数据库文件的相对文件编号
  • BBBBBB 是文件中的块编号
  • RRR 是块内的行编号

所有四个数字都必须采用 Base-64 格式。 如果格式不符,PL/SQL 将引发 VALUE_ERROR 异常。

The CAST function

例子:

-- 在SQL中的CAST
SELECT employee_id, cast (hire_date AS  VARCHAR2 (30))FROM employee;-- PL/SQL中的CAST
hd_display := CAST (SYSDATE AS  VARCHAR2);

详见Table 7-1 Casting Built-In Data Types

The CONVERT function

CONVERT 函数将字符串从一种字符集转换为另一种字符集。

The HEXTORAW function

HEXTORAW 函数将十六进制字符串从 CHAR 或 VARCHAR2 类型转换为 RAW 类型。

The RAWTOHEX function

RAWTOHEX 函数将值从 RAW 类型转换为 VARCHAR2 类型的十六进制字符串。
RAWTOHEX 始终返回可变长度字符串值。

The ROWIDTOCHAR function

ROWIDTOCHAR 函数将 ROWID 类型的二进制值转换为 VARCHAR2 类型的字符串。

该函数返回的字符串格式为OOOOOFFFBBBBBBRRR

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/702560.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[10] v-model补充

目录 自定义组件的 v-modelv-model简化代码 自定义组件的 v-model 组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件。 <input v-model"parentData"> 等价于&#xff1a; <input :value"parentData"input"parentData …

C++从入门到精通 第十七章(终极案例)

写在前面&#xff1a; 本系列专栏主要介绍C的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程&#xff0c;笔者的原创部分主要在示例代码的注释部分。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C教材&#xff08;比…

Yolov8有效涨点:YOLOv8-AM,添加多种注意力模块提高检测精度,含代码,超详细

前言 2023 年&#xff0c;Ultralytics 推出了最新版本的 YOLO 模型。注意力机制是提高模型性能最热门的方法之一。 本次介绍的是YOLOv8-AM&#xff0c;它将注意力机制融入到原始的YOLOv8架构中。具体来说&#xff0c;我们分别采用四个注意力模块&#xff1a;卷积块注意力模块…

Django定时任务之django_apscheduler使用

Django定时任务之django_apscheduler使用 今天在写一个任务需求时需要用到定时任务来做一部分数据处理与优化&#xff0c;于是在了解完现有方法&#xff0c;结合自己需求决定使用django_apscheduler&#xff0c;记录一下过程&#xff0c;有几篇值得参考的文章放在结尾&#xf…

大数据构建知识图谱:从技术到实战的完整指南

文章目录 大数据构建知识图谱&#xff1a;从技术到实战的完整指南一、概述二、知识图谱的基础理论定义与分类核心组成历史与发展 三、知识获取与预处理数据源选择数据清洗实体识别 四、知识表示方法知识表示模型RDFOWL属性图模型 本体构建关系提取与表示 五、知识图谱构建技术图…

Java基础常见八股文学习总结1

Java基础常见八股文学习总结1 SPI SPI 即 Service Provider Interface &#xff0c;字面意思就是&#xff1a;“服务提供者的接口”&#xff0c;我的理解是&#xff1a;专门提供给服务提供者或者扩展框架功能的开发者去使用的一个接口。SPI 将服务接口和具体的服务实现分离开来…

C语言中的数据结构选择与实现

大家好&#xff0c;今天给大家介绍C语言中的数据结构选择与实现&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 一、引言 在C语言中&#xff0c;数据结构是实现高效算法的关键。…

一个更好的IP工具箱MyIP

什么是 MyIP &#xff1f; MyIP 是一个完全开源的 IP 信息查看器&#xff0c;可以轻松检查你的 IP&#xff0c;IP 地理位置&#xff0c;检查 DNS 泄漏&#xff0c;检查 WebRTC 连接&#xff0c;速度测试&#xff0c;ping 测试&#xff0c;MTR 测试&#xff0c;检查网站可用性等…

Codeforces Round 928 G. Vlad and Trouble at MIT

原题链接&#xff1a;Problem - G - Codeforces 题目大意&#xff1a;一颗树&#xff0c;一个n个节点&#xff0c;每个节点上有一种标记&#xff0c;共有三种标记分别是CSP&#xff0c;要求不能让P连接到S&#xff0c;断开一条边的代价为1&#xff0c;最少需要断开几条边&…

docker 安装mysql8 实现互为主从

目录结构 先按照这个目录结构创建。 mysql.conf 配置&#xff0c;mysql的基础可以在此添加 mysql配置 mysql-master下conf配置 [mysqld] # 设置服务器唯一标识号 server-id1 # 启用二进制日志 log-binmaster-bin # 指定需要复制的数据库 binlog-do-dbtest_db # 指定二进制日…

软件游戏显示d3dx9_42.dll丢失的5种解决方法,快速解决dll问题

当计算机系统中d3dx9_42.dll文件丢失时&#xff0c;可能会引发一系列运行问题和功能异常&#xff0c;具体表现形式多样且影响范围较广。首先&#xff0c;对于依赖于DirectX 9.0c版本的各类应用程序&#xff0c;尤其是部分经典的老款游戏&#xff0c;由于d3dx9_42.dll是其中不可…

【Python】OpenCV-图片差异检测与标注

图片差异检测与标注 在图像处理领域中&#xff0c;检测两张图片之间的差异是一项重要的任务。本文将介绍一个使用OpenCV库进行图片差异检测的简单示例代码&#xff0c;并详细注释每个步骤。 1. 引言 图片差异检测是在两张图片之间寻找差异点或区域的过程。这项技术可用于监测…

顺序表知识点——顺序表的增删查改

目录 准备文件 创建顺序表蓝图 顺序表初始化函数接口 顺序表的销毁函数接口 顺序表的打印函数接口 顺序表的插入函数接口 顺序表的删除函数接口 从本节开始&#xff0c; 复习数据结构。 空间复杂度还有时间复杂度之后利用例题学习。 这节先学习顺序表的增删查改。 首…

LeetCode49 字母异位词分组

LeetCode49 字母异位词分组 在这篇博客中&#xff0c;我们将探讨 LeetCode 上的一道经典算法问题&#xff1a;字母异位词分组。这个问题要求将给定的字符串数组中的字母异位词组合在一起&#xff0c;并以任意顺序返回结果列表。 问题描述 给定一个字符串数组 strs&#xff0…

并发编程基础

为什么开发中需要并发编程&#xff1f; 加快响应用户的时间使你的代码模块化、异步化、简单化充分利用CPU资源 基础概念 进程和线程 进程 我们常听说的应用程序&#xff0c;由指令和数据组成。当我们不运行应用程序时&#xff0c;这些应用程序就是放在磁盘上的二进制的代码…

【MATLAB】mlptdenoise信号分解+FFT傅里叶频谱变换组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 展示出图效果 1 mlptdenoise分解算法 MLPT denoise&#xff08;Maximum Likelihood Parameter-Tuned Denoise&#xff09;是一种基于小波变换的信号分解算法&#xff0c;它可以将信号分解为多个具有不同频率特性的小波分…

LeetCode 2859.计算K置位下标对应元素的和

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 请你用整数形式返回 nums 中的特定元素之 和 &#xff0c;这些特定元素满足&#xff1a;其对应下标的二进制表示中恰存在 k 个置位。 整数的二进制表示中的 1 就是这个整数的 置位 。 例如&#xff0c;21 的二进制表示…

Threejs 实现3D影像地图,Json地图,地图下钻

1.使用threejs实现3D影像地图效果&#xff0c;整体效果看起来还可以&#xff0c;底层抽象了基类&#xff0c;实现了通用&#xff0c;对任意省份&#xff0c;城市都可以只替换数据&#xff0c;即可轻松实现效果。 效果如下&#xff1a; 链接https://www.bilibili.com/video/BV1…

Javascript 函数和对象

【六】函数 函数&#xff08;Function&#xff09;是一种可重复使用的代码块&#xff0c;用于执行特定的任务或计算&#xff0c;并可以接受参数和返回值。 【1】函数声明 function functionName(parameter1, parameter2, ...) {// 函数体// 执行特定的任务或计算// 可以使用…

H5/CSS 笔试面试考题(91-100)

简述div 元素的哪些 CSS 属性的默认值为 0 ( ) A:border-top-width B:outline-width C:padding-top D:margin-top 面试通过率:76.0% 推荐指数: ★★★ 试题难度: 初级 试题类型: 选择题 答案:c、d 简述下列关于背景定位属性 background-position 说法正确的是 ( ) A:…