Oracle Sequence generator syntax - sql

The basic syntax for creating a sequence generator for oracle database table attribute is:
CREATE SEQUENCE customers_seq
START WITH 1000
INCREMENT BY 1
NOCACHE
NOCYCLE;
I would like to know what does the NOORDER clause in the SEQUENCE syntax do? If I include the NOORDER clause, will it give me a sequence keeping the increment value random???

This is important when running in parallel server mode or in a cluster. ORDER guarantees that the sequences numbers are ordered.
Example of “noorder” sequence in 10g RAC:
Session 1 on node-A: nextval -> 101
Session 2 on node-A: nextval -> 102
Session 1 on node-B: nextval -> 121
Session 1 on node-B: nextval -> 122
Session 1 on node-A: nextval -> 103
Session 1 on node-A: nextval -> 104
NOORDER in combination with CACHING sequences results in this behavior. ORDER effectively makes the CACHE setting unused. With caching set to 10 when a session gets a sequences it takes 10 sequences into it's cache.

Related

Oracle sql format max number 99999999999

Is the number 9999999999999999999999999999 can be written better?
I have multiple queries with that value.
CREATE SEQUENCE "INVOICES_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 21 CACHE 20 NOORDER NOCYCLE ;
I don't believe you need to write out the maxvalue. Use NOMAXVALUE, which caps at the 28-digit number.
You could also replace MINVALUE 1 with NOMINVALUE.
ORACLE DOCS:
NOMAXVALUE Specify NOMAXVALUE to indicate a maximum value of 10 27th power
for an ascending sequence or -1 for a descending sequence. This is the
default.
NOMINVALUE Specify NOMINVALUE to indicate a minimum value of 1 for
an ascending sequence or -10 26th power for a descending sequence. This is the
default.
CREATE SEQUENCE "invoices_seq" NOMINVALUE NOMAXVALUE INCREMENT BY 1 START WITH 21 CACHE 20 NOORDER NOCYCLE;
It is good practice to specify only non-default settings.
All of those values except the starting value are the defaults and therefore don't need to be stated (and in my view shouldn't be), so the same sequence can be created more concisely using
create sequence invoices_seq start with 21;
For the more general case in your question title, 9999999999999999999999999999 is 1e28 - 1.

Sequence id is not properly inserted

I have created a sequence but its not inserting ids in sequence order.
For Ex:
First I have created one set of record seq number generated as 1, 2, 3, 4
Again I have created another set of records seq started from 8, 9, 10
For 3rd time I have created another set of records seq id got generated as 5, 6, 7
(which is not correct, I want the seq id to be continued as 11, 12, 13)
So 5, 6, 7 is wrong, I need 11, 12, 13 to be generated
What's wrong in my below sequence create query?
CREATE SEQUENCE "LEASE_REPAYMENT_SEQ"
MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1
START WITH 146724 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE GLOBAL ;
If you check the sequence definition, you'll see that you define it as NOORDER.
The Oracle Documentation says
Specify NOORDER if you do not want to guarantee sequence numbers are generated in order of request. This is the default.
So what you see is an expected bahaviour and I assume your database is a RAC instance (as this effect can be observed on RAC only).
Having said that, there are good reasons to allow this small dis-order of the assigned IDs (which is caused by the caching as each RAC instance gets it own cache size to work with).
The positive side of this apprach is that there is no need to synchronize the sequence between the instances - a task that could produce a big overhead.

for every two record increment the sequence - odoo 10

How to increment the sequence in every two records
for ex :
Record 1 : sequence : 1
Record 2 : sequence : 1(the same number)
Record 3 : sequence : 2
Record 4 : sequence : 2(the same sequence)
What is the best condition that i can use it to achieve this result in odoo 10
Regards
You would have to inherit the create method of said model. In that method you have to check what the current sequence is (it's in 'ir.sequence'). Once you have the current sequence you can do a search to see how many times the sequence is used. If less than 2, use that sequence. Else ask the sequence model to give you a new sequence and use that when you are creating the new record.

What is the purpose of the "START WITH" part of a SQL sequence?

In oracle SQL, a sequence is dfined like so :
CREATE SEQUENCE sup_seq
MINVALUE 1
MAXVALUE 999
START WITH 5
INCREMENT BY 1
CACHE 20;
What is the point of having the "START WITH" part ? If we have a minimum value , doesn't that imply that we start with that value? What is useful regarding START WITH ?
Normally, it would be pretty unusual to specify both MINVALUE and START WITH when defining a sequence and to have those values be different. Personally, I don't think that I've ever explicitly specified a MINVALUE since I find START WITH to be more self-explanatory.
One case where two values would be useful would be a sequence that is set to cycle. For example
CREATE SEQUENCE sup_seq
MINVALUE 1
MAXVALUE 999
START WITH 5
INCREMENT BY 1
CACHE 20
CYCLE;
would start with 5 (the start with), generate values through 999 (the maxvalue), and then restart at 1 (the minvalue). That's not a particularly common use case but it's entirely possible.

Alternating true/false flag for current time given step

I have a query being executed every X milliseconds. As a part of result I would like to have alternating true/false flag. This flag should change whenever the query is executed again.
Example
Sample query: select 1, <<boolean alternator>>;
1st execution returns: 1 | true
2nd execution returns: 1 | false
3rd execution returns: 1 | true
and so on. It does not matter if it returns true or false for the first time.
For cases when X is odd number of seconds I have the following solution:
select
mod(right(extract(epoch from current_timestamp)::int::varchar,1)::int, 2) = 0
as alternator
This extracts last digit from epoch and then test if this is even number. Because X is defined as odd number, this test will alternate from one execution to another.
What would work in the same way when X is different - even or not in whole seconds? I would like to make it work for X like 500ms, 1200ms, 2000ms, ...
Note: I plan to use this with PostgreSQL.
I suggest a dedicated SEQUENCE.
CREATE SEQUENCE tf_seq MINVALUE 0 MAXVALUE 1 START 0 CYCLE;
Each call with nextval() returns 0 / 1 alternating. You can cast to boolean:
0::bool = FALSE
1::bool = TRUE
So:
SELECT nextval('tf_seq'::regclass)::int::bool;
To keep other roles from messing with the state of the sequence, only
GRANT USAGE ON SEQUENCE tf_seq TO $dedicated_role;. Run your query as that role or create a function with SECURITY DEFINER and ALTER FUNCTION foo() OWNER TO $dedicated_role;
Or, simpler yet, just make it the column default and completely ignore it in your inserts:
ALTER TABLE foo ALTER COLUMN bool_col
SET DEFAULT nextval('tf_seq'::regclass)::int::bool;
You need to grant USAGE on the sequence to roles that can insert.
Every next row gets the flipped value automatically.
The usual notes for sequences apply. Like, if you roll back an INSERT, the sequence stays flipped. Sequence states are never rolled back.
A temporary table can save the boolean state:
create temporary table t (b boolean);
insert into t (b) values (true);
with u as (
update t
set b = not b
returning b
)
select 1, b
from t;
I would do the same (boolean flipping with not b) with a pltcl function.
Advantage: variable is cached in your session tcl interpreter. Disadvantage: Any pl??? function has a call overhead.
Test table, insert some values:
strobel=# create table test (i integer);
CREATE TABLE
strobel=# insert into test (select * from generate_series(1, 10));
INSERT 0 10
The function:
create or replace function flipper () returns boolean as $$
if {![info exists ::flag]} {set ::flag false}
return [set ::flag [expr {! $::flag}]]
$$ language pltcl volatile;
The test:
strobel=# select *, flipper() from test;
i | flipper
----+---------
1 | t
2 | f
3 | t
4 | f
5 | t