oracle中select的顺序和大小写

发布于 2024-12-10 11:24:52 字数 987 浏览 0 评论 0原文

我正在尝试执行此查询(在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; 

我得到了这个结果:

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 脚本完成,但我不能。

感谢您!

I'm trying to do this query (in oracle) but I have some problems:

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; 

I'm getting this results:

COL_1
----------------------------------------------
191next20
192curr
193curr
194next20
195curr
196curr
197next10
198next20
199next10
200curr
201next20
202curr
203next20
204next10
205next20
206next10
207next10

And this is what I think they should be:

COL_1
----------------------------------------------
191next20
192curr
193curr
194next20
194curr
194curr
197next10
198next20
199next10
199curr
201next20
201curr
203next20
204next10
205next20
206next10
207next10

So, why i get the next value of the sequence also when I should have the current value and not only when the case selects the next value?
Yeah, this could be done with a plsql script but I can't.

Thanks you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

佞臣 2024-12-17 11:24:52

Nextvalcurrval 不是函数,而是“序列伪列"。

“在包含对 NEXTVAL 的引用的单个 SQL 语句中,Oracle 将序列递增一次:对于 SELECT 语句的外部查询块返回的每一行。这样的查询块可以出现在以下地方......”(强调)[Oracle 数据库 SQL 语言参考, “如何使用序列值”]

换句话说,seq.nextval不是一个带有边的函数影响,而是每行具有特定值的伪列。一旦存在对 seq.nextval 的单个引用,每行的值都会递增,无论是否使用该值。 OP 看到的结果是序列所特有的,而不是 case 表达式。例如,解码也是如此:

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

Nextval and currval are not functions, but are "Sequence Pseudocolumns".

"Within a single SQL statement containing a reference to NEXTVAL, Oracle increments the sequence once: For each row returned by the outer query block of a SELECT statement. Such a query block can appear in the following places. ..." (emphasis added) [Oracle Database SQL Language Reference, "How to Use Sequence Values"]

In other words, seq.nextval is not a function with a side affect, but a pseudocolumn that has a particular value per row. Once there is a single reference to seq.nextval, the value increments for every row, whether or not the value is used. The outcome OP is seeing is a peculiar to sequences, not case expressions. For example, same thing with decode:

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
情泪▽动烟 2024-12-17 11:24:52

有趣的。根据 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;

我必须承认这与我的预期不同。

编辑:
查看 ShannonSeverance 的回答

Interesting. Per the Oracle docs:

The statements in a WHEN clause can modify the database and call
non-deterministic functions. There is no fall-through mechanism as in
the C switch statement

Notice it doesn't say the statements in the "true" WHEN clause. So even if the when statement is false, the nextval will fire:

select
case when 1=0 then 'next ' || seq_id.nextval
     when 1=1 then 'curr ' || seq_id.currval
end col1
from dual;

I must admit this is different than I expected.

EDIT:
See answer from ShannonSeverance

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文