在块中使用的所有变量都必须在块的声明部分中声明。(唯一的例外是,迭代整数值范围的 FOR
循环的循环变量自动声明为整数变量,类似地,迭代游标结果的 FOR
循环的循环变量自动声明为记录变量。)
pl/sql 变量可以具有任何 SQL 数据类型,例如 integer
、varchar
和 char
。
这里是一些变量声明的示例:
user_id integer; quantity numeric(5); url varchar(64); myrow tablename%ROWTYPE; myfield tablename.columnname%TYPE; arow RECORD;
变量声明的一般语法如下:
name
[ CONSTANT ]type
[ NOT NULL ] { DEFAULT | := }expression
;
如果给定了 DEFAULT
子句,则指定在输入块时分配给变量的初始值。
如果未给出 DEFAULT
子句,则会将变量初始化为 SQL 空值。
CONSTANT
选项防止在初始化后对变量进行分配,因此其值将在块的持续时间内保持不变。
如果指定了 NOT NULL
,则将空值分配给它会导致运行时错误。
所有声明为 NOT NULL
的变量都必须指定一个非空默认值。
示例:
quantity integer DEFAULT 32; url varchar(64) := 'http://mysite.com'; user_id CONSTANT integer := 10;
声明的函数参数名的数据类型可以是 SQL 参数类型或 pl/sql 参数类型。并且您可以使用 in、 out 和 inout来修改参数。例如:
CREATE FUNCTION sales_tax(subtotal in real) RETURN real IS BEGIN RETURN subtotal * 0.06; END; /
如果匿名块需要函数返回值时,使用inout修饰参数,return返回值必须要有具体的返回值,不然返回的就是一个record。例如:
create table nested_tab(id int, name varchar2(100), job varchar2(100), age int); insert into nested_tab values (2, 'sdfsd', 'cvxvx', 14); create or replace function nested_func(id1 inout int, name1 inout varchar2(100), job1 inout varchar2(100), age1 inout int) return int as id2 int; name2 varchar2(100); job2 varchar2(100); age2 int; begin select * into id2, name2, job1, age1 from nested_tab where age = 14; id1 := id2; name1 := name2; job1 := job2; age1 := age2; begin id1 := 45; name1 := 'name'; job1 := 'job'; age1 := 45; end; return 0; end; / create or replace function nested_func12(id1 inout int, name1 inout varchar2(100), job1 inout varchar2(100), age1 inout int) return int as retcode int; begin begin retcode := nested_func(id1, name1, job1, age1); end; return 1; end; / declare id2 int; name2 varchar2(100); job2 varchar2(100); age2 int; retcode int; begin begin retcode := nested_func12(id2, name2, job2, age2); end; dbms_output.put_line(id2 || name2 || job2 || age2); end; /
variable
%TYPE
%TYPE
提供变量或表列的数据类型。您可以使用它来声明将保存数据库值的变量。例如,假设在您的 users
表中有一个名为 user_id
的列。要声明一个与 users.user_id
具有相同数据类型的变量,您可以编写:
user_id users.user_id%TYPE;
通过使用 %TYPE
,您不需要知道所引用的结构的数据类型,最重要的是,如果所引用的项目的数据类型在将来发生更改(例如:将 user_id
的类型从 integer
更改为 real
),您可能不需要更改函数定义。
在多态函数中,%TYPE
特别有价值,因为内部变量所需的数据类型可能会从一次调用到下一次调用发生变化。可以通过将 %TYPE
应用于函数的参数或结果占位符来创建适当的变量。
%TYPE
也可以用来声明包类型变量。要声明一个数据类型与 package.variable 相同的变量,您可以这样写:
var package.variable%TYPE;
name
table_name
%ROWTYPE
;
复合类型的变量称为 行 变量(或 行类型 变量)。这样的变量可以保存 SELECT
或 FOR
查询结果的整行,只要该查询的列集与变量的声明类型匹配即可。
访问行值的各个字段使用通常的点标记法,例如 rowvar.field
。
可以使用 table_name
%ROWTYPE
符号将行变量声明为具有与现有表或视图的行相同类型的变量;或者可以通过给出复合类型的名称来声明它。
(由于每个表都有与其名称相同的关联复合类型,因此实际上在 LightDB 中无论您是否编写 %ROWTYPE
都无关紧要。但是带有 %ROWTYPE
的形式更具可移植性。)
name
RECORD;
记录变量类似于行类型变量,但它们没有预定义的结构。它们在 SELECT
或 FOR
命令期间分配的行上采用实际的行结构。记录变量的子结构可能每次分配给它时都会发生变化。
这样的结果是,直到首次分配给记录变量之前,它没有子结构,任何尝试访问其中的字段都会引发运行时错误。
请注意,RECORD
不是真正的数据类型,只是一个占位符。还应该意识到,当声明一个返回类型为 record
的函数时,这与记录变量的概念并不完全相同,尽管这样的函数可能使用记录变量来保存其结果。在两种情况下,当编写函数时,实际的行结构是未知的,但对于返回 record
的函数,在解析调用查询时确定实际结构,而记录变量可以在运行时更改其行结构。
name
EXCEPTION;
异常类型用来申明用户自定义异常变量,在申明变量之后使用PRAGMA EXCEPTION_INIT(exception_variable, error_code)
命令来初始化异常代码。
请注意,EXCEPTION
变量的取值范围在除-1403外的大于-100000的负数和正数100。