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

目录

二、数据类型

1.复合类型

记录类型

记录类型定义方式

记录类型的操作

表类型

嵌套表

可变数组

记录类型与表类型的区别

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

3.LOB(long object)类型

LOB类型的种类

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


二、数据类型

1.复合类型

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

记录类型

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

记录类型定义方式

基于数据库对象声明

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

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

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表结构相同的记录类型变量:

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'));
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE('No employee found with ID 1.');
    WHEN TOO_MANY_ROWS THEN
        DBMS_OUTPUT.PUT_LINE('More than one employee found with ID 1.');
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
END;

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

自定义记录类型

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

DECLARE
    TYPE employee_type IS RECORD (
        emp_id employees.employee_id%TYPE,
        emp_name VARCHAR2(50),
        emp_salary employees.salary%TYPE
    );
    emp_record employee_type; -- 定义一个自定义记录类型变量
BEGIN
    emp_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。

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。

--比较两个记录是否相等
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数据类型(包括其他嵌套表类型)。

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

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

TYPE varray_type_name IS VARRAY(size) OF element_type;
  • varray_type_name:VARRAY类型的名称。
  • size:VARRAY可以包含的最大元素数量。
  • element_type:VARRAY中元素的类型。
DECLARE
    TYPE StringVarrayType IS VARRAY(5) OF VARCHAR2(30);
    my_string_varray StringVarrayType := StringVarrayType('A', 'B', 'C', 'D');
BEGIN
    -- 使用VARRAY
    FOR i IN 1..my_string_varray.COUNT LOOP
        DBMS_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:引用表的一行。

你可能感兴趣的:(PL/SQL,sql,数据库,oracle)