前言
PL/SQL是Oracle数据库中的一种嵌入式语言,其功能强大,可以进行存储过程和函数的编写,帮助开发者快速高效地处理数据库操作。
最好的学习是实践加上看官方文档。官方文档中的代码例更是精华和重点所在。 IT行业如此,编程如此,Oracle PL/SQL的学习更是如此。
本系列将以《Database PL/SQL Language Reference》的PL/SQL代码例为主线进行介绍。
Oracle PL/SQL基础语法学习15:静态表达式
Static Expressions(静态表达式)介绍
静态表达式是一个在PL/SQL语言中用于描述一个特定值的表达式。 这个表达式在编译时可以确定其值的表达式,即它不包括字符比较、变量或函数调用,在运行时是不可改变的,常常在PL/SQL中用于初始化变量、常量、参数等。 在PL/SQL中,静态表达式可以使用常量、字面量、枚举类型等,可以使用任意组合来描述目标值。
静态常量
在一个包规范中声明静态常量的语法是:
代码语言:javascript复制constant_name CONSTANT data_type := static_expression;
静态表达式的类型必须与data_type相同(BOOLEAN或PLS_INTEGER)。 静态常量必须始终作为package_name.constant_name被引用,即使是在package_name包的主体中。
官方文档Static Constants(静态常量)代码例
代码语言:javascript复制CREATE PACKAGE my_debug IS
debug CONSTANT BOOLEAN := TRUE;
trace CONSTANT BOOLEAN := TRUE;
END my_debug;
/
CREATE PROCEDURE my_proc1 AUTHID DEFINER IS
BEGIN
$IF my_debug.debug $THEN
DBMS_OUTPUT.put_line('Debugging ON');
$ELSE
DBMS_OUTPUT.put_line('Debugging OFF');
$END
END my_proc1;
/
CREATE PROCEDURE my_proc2 AUTHID DEFINER IS
BEGIN
$IF my_debug.trace $THEN
DBMS_OUTPUT.put_line('Tracing ON');
$ELSE
DBMS_OUTPUT.put_line('Tracing OFF');
$END
END my_proc2;
/
这段PL/SQL代码创建了一个名为my_debug的包,其中包含两个静态常量debug和trace,类型为BOOLEAN,并在其值上分别定义为TRUE,用于控制多个PL/SQL单元中的调试和跟踪。 接着创建了两个存储过程my_proc1和my_proc2,它们都具有AUTHID DEFINER权限,也就是使用它们的用户必须拥有它们的owner授予的权限。这两个存储过程中都使用了条件编译语句IF/THEN/ELSE/END,通过判断my_debug包中的debug和trace常量的值来输出相应的信息。IF指令用于测试编译时常量的值,如果值为TRUE,则执行THEN指定的代码块,否则执行$ELSE指定的代码块。这种条件编译语句通常用于开发和调试过程中,在编译时根据一些条件选择性地编译特定的代码块,以提高代码的可读性和效率。
过程my_proc1仅使用debug,而过程my_proc2仅使用trace,但两个过程都依赖于该包。但重新编译的代码可能并不会有所不同。例如,如果您只更改debug的值为FALSE,然后重新编译这两个过程,那么my_proc1的编译代码会改变,但my_proc2的编译代码不会改变。
关于AUTHID DEFINER 和AUTHID CURRENT_USER
AUTHID参数用于定义执行函数体时,使用哪个用户的权限。
代码语言:javascript复制AUTHID { CURRENT_USER|DEFINER}
- 当创建具有 AUTHID CURRENT_USER 权限的存储过程、函数或包时,其将在调用它的用户的权限上下文中运行。 例:
CREATE OR REPLACE PROCEDURE TEST_AUTHID1 AUTHID CURRENT_USER IS
BEGIN
EXECUTE IMMEDIATE 'select * from table1';
END TEST_AUTHID1 ;
/
该代码创建了名为 TEST_AUTHID 的存储过程,该存储过程以当前用户的上下文权限来运行(即 AUTHID CURRENT_USER)。在存储过程的主体中,使用 EXECUTE IMMEDIATE 语句来执行了一个 SQL 查询,查询的是名为 table1 的表的所有数据。
由于存储过程是以当前用户的权限来运行的,因此只有当前用户具有足够的权限才能执行该查询。如果当前用户没有对表 table1 的访问权限,则该查询将失败并抛出异常。
- 当创建具有 AUTHID DEFINER 权限的存储过程、函数或包时,它将以其所属用户(创建者)的权限上下文中运行。
例:
代码语言:javascript复制CREATE OR REPLACE PROCEDURE TEST_AUTHID2 AUTHID DEFINER IS
BEGIN
EXECUTE IMMEDIATE 'select * from table1';
END TEST_AUTHID2 ;
/
该代码创建了名为 TEST_AUTHID2 的存储过程,该存储过程以定义者 AUTHID 的权限来运行。在存储过程的主体中,使用 EXECUTE IMMEDIATE 语句来执行了一个 SQL 查询,查询的是名为 table1 的表的所有数据。
由于该存储过程是以定义者的权限来运行的,即创建该存储过程的用户/角色/授权程序的权限上下文中运行。因此,只要该定义者具有访问表 table1 的权限,无论调用该存储过程的用户具有何种权限,该查询都会成功执行。 但是,如果定义者在创建存储过程时已经不存在或者权限被撤销,则该存储过程无法成功执行。
参考:
代码语言:javascript复制8.14 Invoker’s Rights and Definer’s Rights (AUTHID Property)
https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/plsql-subprograms.html#GUID-41D23DE7-3C07-41CF-962B-F92B696594B5
Definer’s Rights and Invoker’s Rights (AUTHID clause)
https://docs.oracle.com/en/database/other-databases/timesten/22.1/security/privileges-pl-sql-objects.html#GUID-03BDF2C9-4F55-4584-BAB8-8F38C54018AA
参考连接
代码语言:javascript复制Database PL/SQL Language Reference
https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/plsql-language-fundamentals.html#GUID-6CDF1EB6-913D-48E7-AFDA-DB4DE45209CE
总结
静态表达式是PL/SQL编程中一个重要的概念,它可以用于定义和初始化变量、参数和常量等。常量表达式、字面量表达式和枚举类型表达式是常用的静态表达式类型。AUTHID参数可以用于定义执行函数体时,使用哪个用户的权限。