Oracle with as子句问题汇总

1.with子句的作用

实际上, Oracle可以利用with子句为子查询的数据集作为1个内存临时表. 在内存中解析,提高了执行效率. 而且提高了SQL语句的可读性.

2.with语句的用法与特性

语法很简单:
下面是1个简单的例子:

with 
   A as (select id, name from student)
 
select * from A ;
 
ID          NAME                                                                                                                
---------- --------------
 1         张三
 2         李四
 3         王五
 4         赵六
 5         田七

可以见到, 上面的A为括号的子查询的别名, 相当于在内存里建立了1张临时表. 下面的select 语句就直接检索这张临时表.

下面是一些比较重要的特性

2.1 with子句后必须接着select 语句, 否则出错

例如下面的例子

with 
   Q1 as (select id, name from student)
   
   delete from student where 1 =2 ;
   
   select * from student where 1 =2;
 
在行 2 上开始执行命令时出错:
错误报告:
SQL 错误: ORA-00928: 缺失 SELECT 关键字
00928. 00000 -  "missing SELECT keyword"
2.2 1个with子句里可以定义多个内存临时表, 而且可以互相使用.

如下面的经典例子:

WITH  
Q1 AS (SELECT 3 + 5 S FROM DUAL),  
    Q2 AS (SELECT 3 * 5 M FROM DUAL),  
    Q3 AS (SELECT S, M, S + M, S * M FROM Q1, Q2)  
SELECT * FROM Q3; 
 
         S          M        S+M        S*M
---------- ---------- ---------- ----------
         8         15         23        120 

可以简单上面定义了3个那次临时表Q1, Q2, Q3, 其中Q3 使用了临时表Q1 和 Q2

2.3 with定义的内存临时表一旦被select 语句检索一次, 那么系统就会在内存中清理掉这张临时表

如上面的例子增加一句select * from Q2.

WITH  
Q1 AS (SELECT 3 + 5 S FROM DUAL),  
    Q2 AS (SELECT 3 * 5 M FROM DUAL),  
    Q3 AS (SELECT S, M, S + M, S * M FROM Q1, Q2)  
SELECT * FROM Q3; 
select * from Q2;
 
ORA-00942: 表或视图不存在
00942. 00000 -  "table or view does not exist"
*Cause:    
*Action:
行 4215 出错

出错了, 因为Q2 已经被with里的Q3检索过一次, 被删掉了. 实际上再select 一次 Q3也是会出错的.

可能内存空间珍贵的原因, oracle为with语句设定这个机制

2.4 with子句定义的临时表命不能于已存在的表名重复.

例子

with
   student  as (select id, name from student)
 
select * from student;
 
在行 21 上开始执行命令时出错:
with
   products as (select product_id, product_name from products where rownum <= 10)
 
select * from products 
命令出错, 行: 22 列: 54
错误报告:
SQL 错误: ORA-32039: 递归 WITH 子句必须具有列别名列表

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