Bol*_*lla 5 oracle select sequence
我正在尝试执行此查询(在oracle中),但我遇到了一些问题:
SELECT CASE
WHEN deptno = '10' THEN scott.seq.nextval
|| 'next10'
WHEN deptno = '20' THEN scott.seqnextval
|| 'next20'
WHEN deptno = '30' THEN scott.seq.currval
|| 'curr'
END col_1
FROM scott.emp;
Run Code Online (Sandbox Code Playgroud)
我得到了这个结果:
COL_1 ---------------------------------------------- 191next20 192curr 193curr 194next20 195curr 196curr 197next10 198next20 199next10 200curr 201next20 202curr 203next20 204next10 205next20 206next10 207next10
这就是我认为它们应该是:
COL_1 ---------------------------------------------- 191next20 192curr 193curr 194next20 194curr 194curr 197next10 198next20 199next10 199curr 201next20 201curr 203next20 204next10 205next20 206next10 207next10
那么,为什么我在得到当前值时获得序列的下一个值,而不仅仅是当案例选择下一个值时?是的,这可以用plsql脚本完成,但我不能.
谢谢!
Sha*_*nce 10
Nextval并且currval不是函数,而是" Sequence Pseudocolumns ".
"在包含对NEXTVAL 的引用的单个SQL语句中,Oracle 将序列递增一次:对于 SELECT语句的外部查询块返回的每一行.这样的查询块可以出现在以下位置...."(强调添加)[ Oracle数据库SQL语言参考,"如何使用序列值" ]
换句话说,seq.nextval不是具有副作用的函数,而是每行具有特定值的伪列.一旦有一个引用seq.nextval,无论是否使用该值,每行的值都会递增.结果OP看到的是序列特有的,而不是案例表达.例如,与解码相同:
SQL> select decode(deptno
2 , 10, seq.nextval || 'next10'
3 , 20, seq.nextval || 'next20'
4 , 30, seq.currval || 'curr30')
5 from emp;
DECODE(DEPTNO,10,SEQ.NEXTVAL||'NEXT10',20,SEQ.
----------------------------------------------
35next20
36curr30
37curr30
38next20
39curr30
40curr30
41next10
42next20
43next10
44curr30
45next20
46curr30
47next20
48next10
Run Code Online (Sandbox Code Playgroud)
有趣的。根据 Oracle文档:
WHEN 子句中的语句可以修改数据库并调用非确定性函数。没有像 C switch 语句中那样的失败机制
请注意,它没有说出“true”WHEN 子句中的语句。因此,即使 when 语句为 false,nextval 也会触发:
select
case when 1=0 then 'next ' || seq_id.nextval
when 1=1 then 'curr ' || seq_id.currval
end col1
from dual;
Run Code Online (Sandbox Code Playgroud)
我必须承认这与我的预期不同。
编辑:参见 ShannonSeverance 的回答