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
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;
/
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.
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
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.
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.