Home » SQL & PL/SQL » SQL & PL/SQL » MERGE and SEQUENCE (Oracle 11g)
MERGE and SEQUENCE [message #643104] Tue, 29 September 2015 07:16 Go to next message
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 Go to previous messageGo to next message
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 Go to previous messageGo to next message
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 Go to previous messageGo to next message
_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 #643121 is a reply to message #643115] Tue, 29 September 2015 10:18 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator
Lalit Kumar B wrote on Tue, 29 September 2015 16:25
That's because in case of MERGE , you have total rows affected, rather than having the granularity of rows inserted/updated.


No, that's because Oracle chose to implement and document it as it.
There is no relation between the number of affected rows returned and the behavior of sequence inside MERGE or maybe I missed something.

Re: MERGE and SEQUENCE [message #643129 is a reply to message #643121] Wed, 30 September 2015 00:57 Go to previous messageGo to next message
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 #643131 is a reply to message #643129] Wed, 30 September 2015 01:05 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

So less clear than the documentation I quoted and just confusing.

Re: MERGE and SEQUENCE [message #643132 is a reply to message #643131] Wed, 30 September 2015 01:13 Go to previous messageGo to next message
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 #643133 is a reply to message #643132] Wed, 30 September 2015 01:20 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

1/ This is not in what I quoted, you there just add confusion
2/ No, it should not, it can, and the behavior in this case is clearly described in the documentation, there is no confusion there. How do you write it if you want the next sequence value in both INSERT and UPDATE parts?

I don't see your point adding this post.

Re: MERGE and SEQUENCE [message #643145 is a reply to message #643132] Wed, 30 September 2015 08:10 Go to previous message
Solomon Yakobson
Messages: 3312
Registered: January 2010
Location: Connecticut, USA
Senior Member
Lalit Kumar B wrote on Wed, 30 September 2015 02:13
It 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.

Previous Topic: Recursive query
Next Topic: Unable to pass date variables into a stored procedure
Goto Forum:
  


Current Time: Wed Jul 15 11:31:30 CDT 2026