PL/SQL 变量以及数据类型(下篇)

devtools/2025/2/12 10:51:44/

目录

二、数据类型

1.复合类型

记录类型

记录类型定义方式

记录类型的操作

表类型

嵌套表

可变数组

记录类型与表类型的区别

2.引用类型(未深入研究)

3.LOB(long object)类型

LOB类型的种类

4.属性类型(记录类型中已有示例,不过多赘述)


二、数据类型

1.复合类型

复合类型允许定义更加复杂的数据结构,从而可以在一个变量中存储多个值。

记录类型

记录类型可以包含多个字段,每个字段可以有不同的数据类型。这种数据类型适合用于存储和处理来至表或者游标的行数据。因为它允许将一组相关的数据项组合在一起,每个数据项(又称为域)都有自己的数据类型和名称。

记录类型定义方式

基于数据库对象声明

可以直接基于表、视图或游标的属性%ROWTYPE来声明记录类型。这样声明的记录类型变量将会有着和对应的数据库对象一样的结构,即具有和表的列(或视图、游标的查询结果列)对应的域,每个域的名字和类型都和表中的定义一致。

 假设我们有一个employees的表,其结构如下

sql">CREATE TABLE employees(employee_id NUMBER PRIMARY KEY,first_name VARCHAR2(50),last_name VARCHAR2(50),email VARCHAR2(100),hire_date DATE
)

 在PL/SQL中使用%ROWTYPE来声明一个与employees表结构相同的记录类型变量:

sql">DECLARE-- 声明一个记录类型变量,其结构与employees表一致emp_rec employees%ROWTYPE;
BEGIN-- 查询employees表中的一条记录,并赋值给emp_rec变量SELECT * INTO emp_rec FROM employees WHERE employee_id = 1;-- 输出查询到的记录信息DBMS_OUTPUT.PUT_LINE('Employee ID: ' || emp_rec.employee_id);DBMS_OUTPUT.PUT_LINE('First Name: ' || emp_rec.first_name);DBMS_OUTPUT.PUT_LINE('Last Name: ' || emp_rec.last_name);DBMS_OUTPUT.PUT_LINE('Email: ' || emp_rec.email);DBMS_OUTPUT.PUT_LINE('Hire Date: ' || TO_CHAR(emp_rec.hire_date, 'YYYY-MM-DD'));
EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('No employee found with ID 1.');WHEN TOO_MANY_ROWS THENDBMS_OUTPUT.PUT_LINE('More than one employee found with ID 1.');WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
END;

 这样做的好处是,当数据库对象的结构发生变化时,使用%ROWTYPE声明的变量会自动适应这些变化,从而减少了代码维护的工作量。

自定义记录类型

使用TYPE ... IS RECORD语句来自定义记录类型。在定义中,需要指定记录类型的名称以及它包含的字段和字段的数据类型。还可以为字段指定默认值或是否允许为空(NOT NULL)。

sql">DECLARETYPE employee_type IS RECORD (emp_id employees.employee_id%TYPE,emp_name VARCHAR2(50),emp_salary employees.salary%TYPE);emp_record employee_type; -- 定义一个自定义记录类型变量
BEGINemp_record.emp_id := 100; -- 赋值给记录变量的字段emp_record.emp_name := 'John Doe';emp_record.emp_salary := 5000;DBMS_OUTPUT.PUT_LINE('员工ID: ' || emp_record.emp_id); -- 输出记录变量的内容DBMS_OUTPUT.PUT_LINE('姓名: ' || emp_record.emp_name);DBMS_OUTPUT.PUT_LINE('薪资: ' || emp_record.emp_salary);
END;
记录类型的操作

1.记录赋值

a.直接对记录进行赋值,只要两个记录类型兼容(彼此具有相同数量的和类型的字段)。

b.可以将NULL赋值给记录,这相当于对记录的每个域都赋值为NULL。

sql">DECLARE
record1 employees%ROWTYPE;
record2 employees%ROWTYPE;
BEGIN
record1 := NULL;  --直接赋值为null
record2 := record1;--直接赋值
END;

2.字段引用

使用点(.)操作符来引用记录中的字段。例如,如果有一个记录变量record_var,那么可以通过record_var.field_name来访问该记录的某个字段。

3.比较记录与NULL检查

对记录类型进行比较或NULL检查需要在域层面上操作。即,需要检查记录的每个域来确定记录是否相等或是否为NULL。

sql">--比较两个记录是否相等
IF rec1.field1 = rec2.field1 AND rec1.field2 = rec2.field2 AND ... THEN-- 记录相等
END IF;--检查记录是否为空
IF rec1.field1 IS NULL AND rec1.field2 IS NULL AND ... THEN-- 所有字段都是NULL
ELSE-- 至少有一个字段不是NULL
END IF;
表类型

在PL/SQL中,表类型(Table Types)是用于定义可以在PL/SQL代码中使用的自定义集合(即表)的数据类型。PL/SQL支持两种主要的表类型:嵌套表(Nested Tables)和VARRAY(可变数组)。

嵌套表

嵌套表是一个无序的集合,可以包含零个或多个元素,并且这些元素在运行时可以动态增长和收缩。嵌套表类型使用IS TABLE OF子句来定义,并且可以存储任何PL/SQL数据类型(包括其他嵌套表类型)。

sql">TYPE table_type_name IS TABLE OF element_type [INDEX BY PLS_INTEGER | BINARY_INTEGER];
  • table_type_name:嵌套表类型的名称。
  • element_type:嵌套表中元素的类型。
  • INDEX BY子句是可选的,用于指定嵌套表的索引类型。如果不指定,则默认使用PL/SQL表的无序索引。
sql">DECLARETYPE NumberTableType IS TABLE OF NUMBER;my_number_table NumberTableType := NumberTableType(1, 2, 3, 4, 5);
BEGIN-- 使用嵌套表FOR i IN 1..my_number_table.COUNT LOOPDBMS_OUTPUT.PUT_LINE('Element ' || i || ': ' || my_number_table(i));END LOOP;
END;
可变数组

VARRAY是一个有序集合,其大小在定义时是固定的,但可以在该范围内变化。VARRAY类型使用VARRAY关键字来定义,并且必须指定最大元素数量。

sql">TYPE varray_type_name IS VARRAY(size) OF element_type;
  • varray_type_name:VARRAY类型的名称。
  • size:VARRAY可以包含的最大元素数量。
  • element_type:VARRAY中元素的类型。
sql">DECLARETYPE StringVarrayType IS VARRAY(5) OF VARCHAR2(30);my_string_varray StringVarrayType := StringVarrayType('A', 'B', 'C', 'D');
BEGIN-- 使用VARRAYFOR i IN 1..my_string_varray.COUNT LOOPDBMS_OUTPUT.PUT_LINE('Element ' || i || ': ' || my_string_varray(i));END LOOP;
END;
记录类型与表类型的区别

记录类型(RECORD):记录类型用于存储逻辑相关的数据作为一个单元。它通常包含一个或多个字段,每个字段都有自己的数据类型。记录类型类似于结构体或类的概念,用于封装一组相关的数据。记录中的每个字段可以是标量数据类型(如数字、字符或日期类型)或其他复合数据类型。


表类型(TABLE):表类型用于存储同一数据类型的一系列值,可以看作是一个动态数组。与记录类型不同,表类型的每个元素都是相同的数据类型,这些元素以集合的形式存在,并且表的大小可以在运行时动态改变。

访问和操作方式

记录类型:通过点表示法(.)来访问记录中的字段,如record_variable.field_name。你不能直接对记录类型进行迭代,但可以通过访问其字段来操作数据。


表类型:可以通过索引来访问表中的元素,如table_variable(index)。你可以使用循环结构来迭代表中的所有元素。 

2.引用类型(未深入研究)

引用类型用于存储对数据库对象的引用。

REF CURSOR:用于存储对游标的引用。

3.LOB(long object)类型

LOB(Large Object,大型对象)类型在Oracle数据库中用于存储大型的非结构化数据,如文本、图像、视频和声音等。

LOB类型的种类

a.分为内部LOB和外部LOB;

b.内部LOB(如BLOB、CLOB、NCLOB)存储在数据库内;

  1. BLOB(Binary Large Object):用于存储大型的二进制对象,如图像、视频和声音文件。BLOB类型的数据可以存储在数据库内部,其大小不能超过4GB。
  2. CLOB(Character Large Object):用于存储大型的字符数据,如文本文件。CLOB支持定长和变长字符集,其大小同样不能超过4GB。从Oracle 9i开始,CLOB可以被转换成CHAR和VARCHAR2类型。
  3. NCLOB(National Character Large Object):用于存储大型的NCHAR类型数据,即支持多字节字符集的字符数据。NCLOB同样可以支持定长和变长字符集,并可以被恢复和复制。
  4. BFILE(Binary File Locator):BFILE是一个指向数据库外部的大型二进制文件的定位器。它允许数据库中的表字段存储一个指向服务器上的大型二进制文件的指针,而不是文件本身。因此,BFILE类型的数据实际上存储在数据库外部的操作系统文件中,其最大尺寸取决于操作系统,但理论上也不能超过4GB。

c.内部LOB可参与事务处理;

d.外部LOB(如BFILE)是存储在数据库表空间外部操作系统文件中大的二进制文件;

e.外部LOB文件不能参与事物处理,换句话说你不能将变化提交或回 滚到一个BFILE中。

 

4.属性类型(记录类型中已有示例,不过多赘述)

%TYPE:引用表列或已知变量的类型。

%ROWTYPE:引用表的一行。


http://www.ppmy.cn/devtools/158186.html

相关文章

通过Chatbox和API实现本地使用DeepSeek(R1满血版)

1、注册用户,申请API DeepSeek满血版api注册链接(注册即送2000万Token) 1.1 注册:https://cloud.siliconflow.cn/i/yl6uVodF 1.2 注册完成之后,申请API密钥 2、下载Chatbox 2.1 下载安装包:https://cha…

IntelliJ IDEA 安装与使用完全教程:从入门到精通

一、引言 在当今竞争激烈的软件开发领域,拥有一款强大且高效的集成开发环境(IDE)是开发者的致胜法宝。IntelliJ IDEA 作为 JetBrains 公司精心打造的一款明星 IDE,凭借其丰富多样的功能、智能精准的代码提示以及高效便捷的开发工…

嵌入式接单/派单网站

1.适合小公司接单或者个人挣钱。 2.适合有小需求快速变现。 快包专业的电子项目定制开发服务平台_我爱方案网 2.立创接单。 https://oshwhub.com/activities/spark2025

declare和less

declare -x LESSCLOSE"/usr/bin/lesspipe %s %s" declare -x LESSOPEN"| /usr/bin/lesspipe %s" declare 是一个在 **Unix/Linux Shell**(如 Bash)中用于声明变量及其属性的命令。它通常用于设置变量的值、类型以及一些特殊属性&a…

Docker安装常用软件说明

1.总体步骤 2.安装tomcat docker run -d -p 8080:8080 --name tomcat1 tomcat:11.0.8 访问tomcat猫首页 出现404 这是正常情况 Docker 默认采用的是 NAT 网络模式,所以会自动创建 IPtable 规则并自动开放端口,所以无需考虑防火墙问题 新版Tomcat已经…

【翻译+论文阅读】DeepSeek-R1评测:粉碎GPT-4和Claude 3.5的开源AI革命

目录 一、DeepSeek-R1 势不可挡二、DeepSeek-R1 卓越之处三、DeepSeek-R1 创新设计四、DeepSeek-R1 进化之路1. 强化学习RL代替监督微调学习SFL2. Aha Moment “啊哈”时刻3. 蒸馏版本仅采用SFT4. 未来研究计划 部分内容有拓展,部分内容有删除,与原文会有…

Github自定义readme文件 个人主页简介 模版

自己写的 样式 # 👋 Hi bro , Im Dduo ! Glad to meet you 😁😍😜- 📚 Im Dduo, a student. Feel free to reach out if youd like to chat or collaborate! 😊 - 💬 Dont hesitate to reach …

基于 STM32 的智能电动车防盗与管理系统

1. 引言 随着电动车的普及,其防盗问题成为广大用户关注的焦点。智能电动车防盗与管理系统不仅能有效防止车辆被盗,还能为用户提供车辆状态监控、远程控制等便捷功能。本文设计了一款基于 STM32 的智能电动车防盗与管理系统,集成了防盗报警、…