您现在的位置是:首页 >技术杂谈 >Oracle Database 23c新特性之无表查询网站首页技术杂谈
Oracle Database 23c新特性之无表查询
简介Oracle Database 23c新特性之无表查询
Oracle 23c 开始支持无表查询,也就是没有 FROM 子句的 SELECT 语句。
无表查询语句
在之前的版本中,我们需要使用 DUAL 表快速查询表达式或者函数的值。Oracle 23c 开始可以省略 FROM 子句和 DUAL 表,以下两种查询语句作用相同:
select sysdate;
SYSDATE
---------
2023-05-28
select sysdate from dual;
SYSDATE
---------
2023-05-28
PL/SQL 支持
Oracle 23c 开始,PL/SQL 程序中也可以省略 FROM 子句,例如:
set serveroutput on
declare
v_date date;
begin
select sysdate
into v_date;
dbms_output.put_line(v_date);
end;
/
2023-05-28
PL/SQL procedure successfully completed.
一般来说,我们可以通过直接赋值的方式给变量赋值。示例中为了演示无表查询使用了 SELECT … INTO 语句。
隐式查询结果
在其他数据库中,我们经常可以看到直接将存储过程中的数据作为结果输出,不过 Oracle 不支持这种方式:
create or replace procedure get_date as
begin
select sysdate;
end;
/
Warning: Procedure created with compilation errors.
SQL>show errors
Errors for PROCEDURE GET_DATE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/3 PLS-00428: an INTO clause is expected in this SELECT statement
SQL>
我们可以利用 Oracle 12c 中引入的隐式查询结果实现这一功能,例如:
create or replace procedure get_date as
l_cursor sys_refcursor;
begin
open l_cursor for
select sysdate;
dbms_sql.return_result(l_cursor);
end;
/
exec get_date;
PL/SQL procedure successfully completed.
ResultSet #1
SYSDATE
---------
2023-05-28
这种方式可以模拟其他数据库中的行为,但是实现要麻烦一些。
实现原理
接下来我们看看新的无表查询语法是如何实现的,本质上它是一个查询转换。
首先,我们刷新一下共享池,并且找出会话的跟踪文件。
conn sys/SysPassword1@//localhost:1521/freepdb1 as sysdba
alter system flush shared_pool;
conn testuser1/testuser1@//localhost:1521/freepdb1
set linesize 100
column value format a65
select value
from v$diag_info
where name = 'Default Trace File';
VALUE
-----------------------------------------------------------------
/opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_17498.trc
然后使用 10053 事件跟踪查看语句的执行情况:
alter session set events '10053 trace name context forever';
select sysdate;
alter session set events '10053 trace name context off';
检查跟踪文件,搜索“Final query after transformations”部分的内容,可以看到以下信息:
Final query after transformations:******* UNPARSED QUERY IS *******
SELECT SYSDATE@! "SYSDATE" FROM "SYS"."DUAL" "DUAL"
查询语句被转换之后包含了 FROM DUAL,因此这就是一个语法糖。无表查询可以更加方便用户使用,而且移植性更好。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。