Reputation:
I would like to generate unique sequence numbers for each order comment as they are entered.
For example, the segment:
INSERT INTO order_comments(order_number,
seq_num,
comment_text,
remark_timestamp)
VALUES (
'Smith',
(SELECT NVL (MAX (seq_num), 0) + 1
FROM order_comments
WHERE order_number='141592'),
'Shipped updated version 1.1’,
current_timestamp);
can be run multiple times, getting a new sequence number for that user each time.
The bad news is when this is written in Pro*C and we have multiple copies running simultaneously, we seem to get locks if we try to insert two comments for the same user at the same time. We could have an order_comment_sequence and just use nextval in the insert but that seems untidy since the “141592” comments will not have sequential numbers.
For the sake of the current discussion, we will say we have a few million orders, each of which will have five or ten comments. The order_number and seq_num are the primary key.
Is there something wrong with doing it this way? Is there an easier way of doing it?
Upvotes: 0
Views: 2462
Reputation: 12486
I don't think you can avoid the "untidy" approach if you want to avoid locks. You can generate a sequence number by ORDER_NUMBER
when retrieving data from the database as follows:
SELECT order_number, ROW_NUMBER() OVER ( PARTITION BY order_number ORDER BY remark_timestamp ) AS seq_num
FROM order_comments
The "sequence" approach given by @benji is one approach. Another is to generate a random number using SYS_GUID():
TO_NUMBER( SYS_GUID(), 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' )
You could even use this on the SEQ_NUM
column as a default:
ALTER TABLE order_comments MODIFY seq_num DEFAULT TO_NUMBER( SYS_GUID(), 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' );
Hope this helps.
Upvotes: 1
Reputation: 606
You can use Oracle Sequence.
First create the sequence, like this:
CREATE SEQUENCE order_comments_seq
MINVALUE 1
MAXVALUE 999999999999999999999999999
START WITH 1
INCREMENT BY 1
CACHE 20;
For more info: http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_6015.htm#SQLRF01314
then you can use sequence.NEXTVAL like this:
INSERT INTO order_comments(order_number,
seq_num,
comment_text,
remark_timestamp)
VALUES ( 'Smith',
order_comments_seq.NEXTVAL,
'Shipped updated version 1.1’,
current_timestamp);
Upvotes: 3