I have created a sequence
CREATE SEQUENCE CA_SEQUENCE_NUMBER_SEQ
start with 9000000000
increment by 1
nocycle
nocache;
The assigned and the start values are the same number. Kindly suggest me what could be the reason
please refer to the image for the clear picture.
this image details are from SYSSEQUENCES Data dictionary view
I would assume that the sequence has been altered. E.g.
CREATE SEQUENCE CA_SEQUENCE_NUMBER_SEQ AS DECIMAL(31,0) start with 7000000000;
values nextval for CA_SEQUENCE_NUMBER_SEQ;
ALTER SEQUENCE CA_SEQUENCE_NUMBER_SEQ restart with 9000000000;
then SYSCAT.SEQUENCES would show
select NEXTCACHEFIRSTVALUE from syscat.sequences where seqname = 'CA_SEQUENCE_NUMBER_SEQ'"
NEXTCACHEFIRSTVALUE
---------------------------------
7000000000.
1 record(s) selected.
but after another call to values nextval for CA_SEQUENCE_NUMBER_SEQ, the NEXTCACHEFIRSTVALUE will update
values nextval for CA_SEQUENCE_NUMBER_SEQ;
1
---------------------------------
9000000000.
1 record(s) selected.
select NEXTCACHEFIRSTVALUE from syscat.sequences where seqname = 'CA_SEQUENCE_NUMBER_SEQ'"
NEXTCACHEFIRSTVALUE
---------------------------------
9000000020.
1 record(s) selected.
It appears that the create statement happened some time ago as >700,000 numbers have been generated from the sequence. It is possible to restart a sequence from anywhere by issuing an ALTER SEQUENCE statement such as:
ALTER SEQUENCE CA_SEQUENCE_NUMBER_SEQ RESTART 7000000000
You can point it back to the starting value specified in the CREATE SEQUENCE statement by using just RESTART like this:
ALTER SEQUENCE CA_SEQUENCE_NUMBER_SEQ RESTART
Here is the relavant section of the documentation:
>>-ALTER SEQUENCE--sequence-name-------------------------------->
.-----------------------------------------------.
V (1) |
>----------+-RESTART--+------------------------+-+-+-----------><
| '-WITH--numeric-constant-' |
RESTART
Restarts the sequence. If numeric-constant is not specified, the sequence is restarted at the value specified implicitly or explicitly as the starting value on the CREATE SEQUENCE statement that originally created the sequence.
WITH numeric-constant
Restarts the sequence with the specified value. This value can be any positive or negative value that could be assigned to a column of the data type associated with the sequence (SQLSTATE 42815), without nonzero digits existing to the right of the decimal point (SQLSTATE 428FA).
Related
I am using dynamically created table partitions to store event information in a Postgresql 13 database. The master table from which the child tables inhert their structure contains an id field with an auto-incrementing sequence. The sequence, master table and trigger for inserts look as follows:
CREATE SEQUENCE event_id_seq
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 9223372036854775807
CACHE 1;
CREATE TABLE event_master
(
id bigint NOT NULL DEFAULT nextval('event_id_seq'::regclass),
event jsonb,
insert_time as timestamp
)
CREATE TRIGGER insert_event_trigger
BEFORE INSERT
ON event_master
FOR EACH ROW
EXECUTE PROCEDURE event_insert_function();
Additionally, the event_insert_function() uses the following code to insert new rows posted to the master table:
EXECUTE format('INSERT INTO %I (event, insert_time) VALUES($1,$2)', partition_name) using NEW.event, NEW.insert_time);
When looking at the sequence numbers in the id field, I only get every other number, i.e. 1,3,5,7, ...
Based on some related information I found, I assume this has something to do with Postgresql counting the initial insert into the master table and the triggered insert into the child table as two occurences. So my first question is, whether this is correct, and if so what's the rational behind it and why not "pass through" the insert from master to child?
More importantly though, what do I need to do to set up a properly incrementing sequence (i.e. returning 1,2,3,4 ...)?
is it Possible to recover from a temporal table?
I defined 2 tables like this:
create table lib.x(
"ID" INTEGER GENERATED ALWAYS AS IDENTITY (
START WITH 1 INCREMENT BY 1
NO MINVALUE NO MAXVALUE
NO CYCLE NO ORDER
CACHE 20
),
char char(1),
row_start TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW BEGIN IMPLICITLY hidden,
row_end TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW END IMPLICITLY hidden,
row_id TIMESTAMP(12) GENERATED ALWAYS AS TRANSACTION START ID IMPLICITLY hidden,
PERIOD SYSTEM_TIME(row_start, row_end)
);
create table lib.x_history like lib.x;
alter TABLE lib.x
ADD VERSIONING USE HISTORY TABLE lib.x_history;
then I did this:
insert into lib.x(char) values('a'), ('b'), ('c');
delete from lib.x where id = 2;
Is it possible to restore the char 'b' with the ID 2?
Yes and no. It is not a system restore, but of course you can query the old state and use it to insert into the regular table. See the section "Querying system-period temporal data" in the Db2 docs.
You would first construct a query to search AS OF. Later, you could use it as input to an insert statement. Thus, you restore the value, but it is treated as deleting the value and inserting it as new.
This question already has answers here:
How do I reset a sequence in Oracle?
(18 answers)
Closed 5 years ago.
I am using Oracle SQL. There is a sequence and trigger used for id that increments from 1 every time a new record is added in the table. However if all the records are deleted and new records to be added this table, the id doesn't starts from 1 whilst it starts from the last maximum number of records recorded in the sequence.
Therefore is there a way in TRIGGER statement where I can reset the sequence if the table is empty and new records get imported.
OR do I have to do stored_procedure way, if that then how can i call this using myBatis mapper?
Table (customer_info)
customer_id customer_name customer_location
1 Arbin USA
2 Tim Canada
3 Rachel Australia
Sequence
CREATE sequence customer_id_seq START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
Trigger
CREATE OR REPLACE TRIGGER customer_id
BEFORE INSERT ON customer_info
FOR EACH ROW
BEGIN
SELECT customer_id_seq.NEXTVAL
INTO :new.customer_id
FROM dual;
END;
/
Thank you.
Once You Truncate the Table. The Sequence has to be Reset to 1.
The simplest way to do it it by dropping and re-creating it again.
DROP SEQUENCE customer_id_seq
CREATE sequence customer_id_seq START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
I added some rows into the table manually and also I set up the ID (auto_increment) manually. Now when I try to add new row through my app into DB table, to DB table I am getting the error , that the created ID value already exist.
How can I set manually the next ID value (for example, in table I have to IDs, so how to tell to PostgreSQL, that the next ID should be counted since the number 3)?
http://www.postgresql.org/docs/current/static/functions-sequence.html
select setval('sequence-name', <new-value>);
You can get the sequence name from the the table definition:
id | integer | not null default nextval('id_seq'::regclass)
In this case the sequence is named 'id_seq'
Edit (10x to #Glenn):
SELECT setval('id_seq', max(id)) FROM table;
I think there is a simpler way:
ALTER SEQUENCE "seq_product_id" RESTART WITH 10
Is it possible in SQL (SQL Server) to retrieve the next ID (integer) from an identity column in a table before, and without actually, inserting a row? This is not necessarily the highest ID plus 1 if the most recent row was deleted.
I ask this because we occassionally have to update a live DB with new rows. The ID of the row is used in our code (e.g. Switch (ID){ Case ID: } and must be the same. If our development DB and live DB get out of sync, it would be nice to predict a row ID in advance before deployment.
I could of course SET IDENTITY OFF SET INSERT_IDENTITY ON or run a transaction (does this roll back the ID?) etc but wondered if there was a function that returned the next ID (without incrementing it).
try IDENT_CURRENT:
Select IDENT_CURRENT('yourtablename')
This works even if you haven't inserted any rows in the current session:
Returns the last identity value generated for a specified table or view. The last identity value generated can be for any session and any scope.
Edit:
After spending a number of hours comparing entire page dumps, I realised there is an easier way and I should of stayed on the DMVs.
The value survives a backup / restore, which is a clear indication that it is stored - I dumped all the pages in the DB and couldn't find the location / alteration for when
a record was added. Comparing 200k line dumps of pages isn't fun.
I had used the dedicated admin console I took a dump of every single internal table exposed inserted a row and then took a further dump of the system tables. Both of the dumps were identical, which indicates that whilst it survived, and therefore must be stored, it is not exposed even at that level.
So after going around in a circle I realised the DMV did have the answer.
create table foo (MyID int identity not null, MyField char(10))
insert into foo values ('test')
go 10
-- Inserted 10 rows
select Convert(varchar(8),increment_value) as IncrementValue,
Convert(varchar(8),last_value) as LastValue
from sys.identity_columns where name ='myid'
-- insert another row
insert into foo values ('test')
-- check the values again
select Convert(varchar(8),increment_value) as IncrementValue,
Convert(varchar(8),last_value) as LastValue
from sys.identity_columns where name ='myid'
-- delete the rows
delete from foo
-- check the DMV again
select Convert(varchar(8),increment_value) as IncrementValue,
Convert(varchar(8),last_value) as LastValue
from sys.identity_columns where name ='myid'
-- value is currently 11 and increment is 1, so the next insert gets 12
insert into foo values ('test')
select * from foo
Result:
MyID MyField
----------- ----------
12 test
(1 row(s) affected)
Just because the rows got removed, the last value was not reset, so the last value + increment should be the right answer.
Also going to write up the episode on my blog.
Oh, and the short cut to it all:
select ident_current('foo') + ident_incr('foo')
So it actually turns out to be easy - but this all assumes no one else has used your ID whilst you got it back. Fine for investigation, but I wouldn't want to use it in code.
This is a little bit strange but it will work:
If you want to know the next value, start by getting the greatest value plus one:
SELECT max(id) FROM yourtable
To make this work, you'll need to reset the identity on insert:
DECLARE #value INTEGER
SELECT #value = max(id) + 1 FROM yourtable
DBCC CHECKIDENT (yourtable, reseed, #value)
INSERT INTO yourtable ...
Not exactly an elegant solution but I haven't had my coffee yet ;-)
(This also assumes that there is nothing done to the table by your process or any other process between the first and second blocks of code).
You can pretty easily determine that the last value used is:
SELECT
last_value
FROM
sys.identity_columns
WHERE
object_id = OBJECT_ID('yourtablename')
Usually, the next ID will be last_value + 1 - but there's no guarantee for that.
Marc
Rather than using an IDENTITY column, you could use a UNIQUEIDENTIFIER (Guid) column as the unique row identifer and insert known values.
The other option (which I use) is SET IDENTITY_INSERT ON, where the row IDs are managed in a source controlled single 'document'.