Alter / Update PostgreSQL Sequence - sql

How can I update the last_value field in my sequence and add 1 to it?
The query I tried: ALTER SEQUENCE "seq_hours" SET 'last_value' = 'last_value' + 1
However this did not work.

Use setval() with a subquery to get the value from a table, e.g.
SELECT setval('seq_hours', (SELECT max(last_value)+1 FROM t));
EDIT: This solution only makes sense if you want to set the current value of a sequence based on a value from a given table. If you only want the next possible value of a sequence you should use nextval as #a_horse_with_no_name suggested (see comments)

Related

How to auto_increment a value from a column when inserting a new row

I know that it seems similar to some questions, but I hope mine is different.
I work with an Oracle Database
I want to have an auto_increment on a column by using
COMPUTED column and LAST_VALUE(column) + 1
So I have the following request :
ALTER TABLE schema.table (
ADD SK NUMBER ALWAYS AS (LAST_VALUE(SK)+1)
);
Is it gonna do the trick with only that ?
Or do I need to add a FOR EACH ROW sentence so that fits with my need of auto_increment ?
EDIT According to G00dy's comment:
The sequence :
create sequence SK_SEQUENCES
increment by 1
start with 1
nomaxvalue
minvalue 1
nocycle
order
keep;
The table :
create table schema.test(
isCurrent CHAR(10),
SK NUMBER
);
If I understand the comment from #g00dy,
I need to add the Sequence as a value for my column SK,
so I have this :
insert into schema.test(SK)
values (SK_SEQUENCES.nextval)
Then ok, it works
But when I'm adding value to the isCurrent column,
there's no auto_increment on the SK column
I guess, to have the auto_increment I need to create a trigger.
Maybe I'll have to use trigger/sequence in order to fix my issue but I don't want to..
No, it won't work.
Firstly, the syntax is generated always, not just always, and there are no brackets around the add clause. However, this still won't work:
alter table demo
add sk integer generated always as (last_value(sk)+1);
fails with:
ORA-30484: missing window specification for this function
because last_value is an analytic function that needs to be part of a query and have a window specification like over (partition by xxx order by yyy). You can't use an analytic function as a column default.
From Oracle 12.1 you can define an identity column as:
alter table demo
add sk integer generated always as identity;
In earlier Oracle versions you would need to either specify the sequence.nextval when inserting, or else create a trigger as
create sequence sk_seq;
create or replace trigger demo_generate_sk_trg
before insert on demo for each row
begin
:new.dummy := sk_seq.nextval;
end;
/

postgresql nextval incorrect result

After restoring database I run next query
SELECT nextval('table_id_seq')
and I must get max id + 1 something like (select max(id) + 1 from table), but instead I get just max id next time I call it result is correct. This issue happens only to two tables the rest works okay. I use PostgreSQL 10.
Any ideas what it can be.
Check "last value" of sequence using below query:
select * from sequence_name
If the last value does not match with table max value then use alter sequence and restart the last value as table max value.

Sqlite add column based on another columns value

I have a first_name field in an SQLite database.
I want to alter this database by adding a first_initial column and make its value the first character of first_name followed by a period.
How do would I go about setting the value of first_initial, can it be done from the alter statement?
ALTER TABLE mytable ADD COLUMN first_initial TEXT;
As far as I know this cannot be done as part of the alter statement. However, you could follow up the alter statement with an update statement to initialize the initial:
UPDATE mytable SET first_initial = SUBSTR(first_name, 1, 1);
Or better yet, if the first_initial is always the first character of first_name, you don't need it in the table at all - you could just query it on demand, or, if you prefer, create a view to retrieve it:
CREATE VIEW myview AS
SELECT *, SUBSTR(first_name, 1, 1) AS first_initial
FROM mytable
I think this might do what you want for any new rows entered (after adding the column as you do in your alter statement). It may need a little tweaking, so here's the reference page on triggers: http://www.sqlite.org/lang_createtrigger.html
CREATE TRIGGER mytable_first_initial_default_value
AFTER INSERT ON mytable
FOR EACH ROW
WHEN NEW.first_initial IS NULL
BEGIN
UPDATE mytable
SET first_initial = substring(NEW.first_name,1,1)
WHERE rowid = NEW.rowid;
END;
However, I'm also inclined to say that you really shouldn't have a duplicate column with dependent information, because it adds a lot more complexity than it does value (in my opinion).
Any time you need to get the first initial, just do this:
SELECT substring(first_name,1,1) AS first_initial FROM mytable

Auto Increment Column value whenever update happen on that row in sql server

I want to maintain a column which will store that how many times a row has been modified.
So whenever the row has been updated I want to increase the column value.
I think I have to use trigger for that.But I am looking for an alternative solution.
IMHO trigger is the way to go, but if you sure that you control all your updates, then you can do as simple as this:
UPDATE mytable
SET somefield='newvalue',
update_count = update_count+1
WHERE id=n
CREATE TRIGGER CountRows
ON TestCount
after Update
AS
Update TestCount set Cnt = Cnt +1 where ID in (select ID from inserted)
GO
whenever some value in a row changes, the grigger adds +1 to the same row's Cnt column value.

select max value of a column in table with no rows

I am using oracle database
While inserting a row in a table, i need to find the max value of a column and increment it by 1, and use that value in row i am inserting.
INSERT INTO dts_route
(ROUTE_ID, ROUTE_UID, ROUTE_FOLDER)
VALUES (
(SELECT MAX(ROUTE_ID) + 1 FROM route) ,
ROUTE_UID,
ROUTE_FOLDER)
This works fine if their is at least one entry in table.
But returns null when their are no entries in table.
How can i get default value of 1 when their are no entries in table.
SELECT COALESCE(MAX(ROUTE_ID),0) ...
This is not a safe way of creating an auto-increment field. You can use an Oracle sequence to achieve this goal.
As for the null, you can use NVL to give a default value (say, 0) in case the function returns null.
Use sequence for the ID. You need to create sequence. See below link
http://www.basis.com/onlinedocs/documentation/b3odbc/sql_sequences.htm
Use:
INSERT INTO dts_route
(ROUTE_ID)
SELECT COALESCE(MAX(r.route_id), 0) +1
FROM ROUTE r
...but you really should be using a sequence to populate the value with a sequential numeric value:
CREATE SEQUENCE dts_route_seq;
...
INSERT INTO dts_route
(ROUTE_ID)
SELECT dts_route_seq.NEXTVAL
FROM DUAL;
Set a default for NULL
SELECT NVL(MAX(ROUTE_ID),0)
though using a sequence might be easier if you don't mind the odd gaps in your route ids
select 0 when null, then it will be 0+1 which is a correct number compared to null+1
SELECT isnull(MAX(ROUTE_ID),0) + 1 FROM route
If you are concerned about there being gaps in your route ids then create the sequence with the NOCACHE clause:
CREATE SEQUENCE dts_route_seq NOCACHE;
Note that there is a performance hit because Oracle now has to "commit" each time you increment the sequence.