| MERGE and SEQUENCE [message #643104] |
Tue, 29 September 2015 07:16  |
 |
yepp
Messages: 4 Registered: September 2015
|
Junior Member |
|
|
Hello,
I'm using a SEQUENCE.NEXTVAL in the INSERT clause of a MERGE statement. It works, but the value of the SEQUENCE is increasing even if there's nothing to insert. Is that normal behaviour? How can I avoid this?
Example:
CREATE SEQUENCE seq_test MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE ORDER NOCYCLE;
CREATE TABLE tab_test
(
id NUMBER(*,0),
nr NUMBER(*,0),
text VARCHAR2(25 CHAR)
);
merge into tab_test z
using (
select 1 nr,
'A' text
from dual
) q on (q.nr = z.nr)
when matched then update set
z.text = q.text
when not matched then insert
(id, nr, text)
values
(seq_test.nextval, q.nr, q.text)
;
select * from tab_test;
-- => 1 | 1 | A
select seq_test.currval from dual;
-- => 1
merge into tab_test z
using (
select 1 nr,
'B' text
from dual
) q on (q.nr = z.nr)
when matched then update set
z.text = q.text
when not matched then insert
(id, nr, text)
values
(seq_test.nextval, q.nr, q.text)
;
select * from tab_test;
-- => 1 | 1 | B
select seq_test.currval from dual;
-- => 2 value of sequence did change without inserting data
merge into tab_test z
using (
select 2 nr,
'C' text
from dual
) q on (q.nr = z.nr)
when matched then update set
z.text = q.text
when not matched then insert
(id, nr, text)
values
(seq_test.nextval, q.nr, q.text)
;
select * from tab_test;
-- => 1 | 1 | B
-- => 3 | 2 | C
select seq_test.currval from dual;
-- => 3
Thank you.
[Updated on: Tue, 29 September 2015 07:35] Report message to a moderator
|
|
|
|
| Re: MERGE and SEQUENCE [message #643112 is a reply to message #643104] |
Tue, 29 September 2015 08:53   |
 |
Michel Cadot
Messages: 68776 Registered: March 2007 Location: Saint-Maur, France, https...
|
Senior Member Account Moderator |
|
|
Yes, it is the normal behavior.
From doc:
Quote:For each row merged by a MERGE statement. The reference to NEXTVAL can appear in the merge_insert_clause or the merge_update_clause or both. The NEXTVALUE value is incremented for each row updated and for each row inserted, even if the sequence number is not actually used in the update or insert operation.
[Updated on: Tue, 29 September 2015 08:54] Report message to a moderator
|
|
|
|
| Re: MERGE and SEQUENCE [message #643115 is a reply to message #643104] |
Tue, 29 September 2015 09:25   |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
yepp wrote on Tue, 29 September 2015 17:46
I'm using a SEQUENCE.NEXTVAL in the INSERT clause of a MERGE statement. It works, but the value of the SEQUENCE is increasing even if there's nothing to insert.
That's because in case of MERGE , you have total rows affected, rather than having the granularity of rows inserted/updated.
|
|
|
|
| Re: MERGE and SEQUENCE [message #643119 is a reply to message #643115] |
Tue, 29 September 2015 10:01   |
_jum
Messages: 577 Registered: February 2008
|
Senior Member |
|
|
May be you could avoid this by using a FUNCTION with RESULT_CACHE rather than the NEXTVAL in the MERGE statement:
CREATE OR REPLACE FUNCTION mseq RETURN INTEGER
RESULT_CACHE
IS
BEGIN
RETURN seq_test.nextval;
END;
But I can't evaluate the side effects of this method, so use it only in test environment.
May be the gurus here can assess better.
[Updated on: Tue, 29 September 2015 10:03] Report message to a moderator
|
|
|
|
|
|
| Re: MERGE and SEQUENCE [message #643129 is a reply to message #643121] |
Wed, 30 September 2015 00:57   |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
What I mean is, if nextval is used in the MERGE statement at least once, then the sequence is incremented for the number of rows merged/affected. The same behavior applies with the new identity columns in 12c.
"N rows merged" implies sequence is increment by N, given that nextval was specified at least once in the MERGE statement.
|
|
|
|
|
|
| Re: MERGE and SEQUENCE [message #643132 is a reply to message #643131] |
Wed, 30 September 2015 01:13   |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
One statement in documentation is not clear enough:
Quote:If NEXTVAL is specified more than once in any of these locations, then the sequence is incremented once for each row and returns the same value for all occurrences of NEXTVAL for that row.
It should be at least once, not more than once.
|
|
|
|
|
|
| Re: MERGE and SEQUENCE [message #643145 is a reply to message #643132] |
Wed, 30 September 2015 08:10  |
Solomon Yakobson
Messages: 3312 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
Lalit Kumar B wrote on Wed, 30 September 2015 02:13It should be at least once, not more than once.
You are confusing number of times NEXTVAL is incremented per row with number of times NEXTVAL is incremented per statement. The former is 1 while the latter is number of affected rows except MERGE where it is total number of matched rows regardless if WHEN MATCHED is used and not matched rows only if WHEN NOT MATCHED is used.
SY.
|
|
|
|