Is there a way to use Ignite built-in ID Generator as described at https://apacheignite.readme.io/docs/id-generator as-is without creating a custom SQL function to insert identity values for the primary key of table ? For instance,
create table test_table (id int primary key, name char(100));
insert into test_table (id, name) values (Ignite built-in ID Generator, "abc");
insert into test_table (id, name) values (Ignite built-in ID Generator, "def");
insert into test_table (id, name) values (Ignite built-in ID Generator, "ghi");
There is a RANDOM_UUID function.
There is also an request for enhancement to have auto-incremented fields.
If you want to use the Ignite's sequences as described on the page you've linked than yes, you have to create your own function.
Related
I have a simple table like this:
CREATE TABLE IF NOT EXISTS myval
(
id integer NOT NULL DEFAULT nextval('myval_myval_id_seq'::regclass),
name character varying(255),
CONSTRAINT "PK_aa671c3359a0359082a84ecb801" PRIMARY KEY (id)
)
the sequence definition is:
CREATE SEQUENCE IF NOT EXISTS myval_myval_id_seq
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 2147483647
CACHE 1
OWNED BY myval.myval_id;
when I insert data along with the primary key:
INSERT INTO myval(id, name) VALUES (1, 'sdf');
INSERT INTO myval(id, name) VALUES (2, 'sdf');
INSERT INTO myval(id, name) VALUES (3, 'sdf');
INSERT INTO myval(id, name) VALUES (4, 'sdf');
then, I insert it without the PK:
INSERT INTO myval(name) VALUES ('new sdf');
it gives an error saying:
duplicate key value violates unique constraint "PK_aa671c3359a0359082a84ecb801",
DETAIL: Key (myval_id)=(1) already exists.
I expected it to start with PK value of 5 but, instead it gives an error. Can we configure postgres to skip conflicting values and generate from the closest available value to use instead of throwing an error?
The best way to avoid such conflicts is to use identity columns - in this case a GENERATED ALWAYS AS IDENTITY seems the right option.
CREATE TABLE IF NOT EXISTS myval
(
id integer GENERATED ALWAYS AS IDENTITY,
name character varying(255),
CONSTRAINT "PK_aa671c3359a0359082a84ecb801" PRIMARY KEY (id)
);
This will work like a sequence (serial), however it will fail if the user tries to manually insert a value in this column
INSERT INTO myval (id,name)
VALUES (1,'foor');
ERROR: cannot insert a non-DEFAULT value into column "id"
DETAIL: Column "id" is an identity column defined as GENERATED ALWAYS.
TIP: Use OVERRIDING SYSTEM VALUE to override.
If for whatever reason you must override this behavior in a certain INSERT statement you can do so using OVERRIDING SYSTEM VALUE, as the error message above suggests
INSERT INTO myval (id,name) OVERRIDING SYSTEM VALUE
VALUES (1,'foo');
You might be able to achieve a sequential value using serial even if the user screws things up with inserts, e.g. using trigger functions. But such an architecture is hard to maintain and imho is definitely not worth the trouble.
Demo: db<>fiddle
We are dealing with legacy code that doesn't auto-increment the primary key (see serial) so I have to manually do it. What is the correct way to manually update the primary key field on insert. I am getting an error when I do the below
Table:
CREATE TABLE pizza (
id bigint not null,
price int
)
Insert statement:
INSERT INTO pizza
(id, price)
VALUES
(
(SELECT max(id) from pizza)+1,
1.75
)
Don't use max()+1 to generate a primary key. It's not safe for concurrent inserts and it doesn't really scale well.
Just create a sequence and use that:
create sequence pizza_id_seq;
Then synchronize it with the current values in the table:
select setval('pizza_id_seq', coalesce(max(id),1))
from pizza;
Then, instead of changing your INSERT statements to use the dreaded max() + 1, just use the sequence:
INSERT INTO pizza
(id, price)
VALUES
(nextval('pizza_id_seq'), 1.75)
I have two table with one to one relation and I want to insert two rows to the tables with the same auto increment id. Is it possible?
create table first
(
id bigint primary key,
value varchar(100) not null
);
create table second
(
id bigint references first (id),
sign boolean
);
insert into first(id, value)
values (-- autoincremented, 'some_value');
insert into second(id, sign)
values (-- the same autoincremented, true);
Your id column must be defined as an "auto increment" one before you can use that:
create table first
(
id bigint generated always as identity primary key,
value varchar(100) not null
);
Then you can use lastval() to get the last generated id:
insert into first(id, value)
values (default, 'some_value');
insert into second(id, sign)
values (lastval(), true);
Or if you want to be explicit:
insert into first(id, value)
values (default, 'some_value');
insert into second(id, sign)
values (currval(pg_get_serial_sequence('first','id')), true);
One option uses a cte with the returning clause:
with i as (
insert into first(value) values('some_value')
returning id
)
insert into second(id, sign)
select i.id, true from i
This performs the two inserts at once; the id of the first insert is auto-generated, and then used in the second insert.
For this to work, you need the id of the first table to be defined as serial.
I have the following table in my database
" CREATE TABLE Q_GROUP ( Id INTEGER PRIMARY KEY ); "
This is only needed to ensure different Items are in the same group. Each time, when adding new items, I need to create a unique group. The items are then connected to this group. The usual syntax for adding items and auto-incrementing the identifier is to specify the items but not the identifier. In this case, sq lite gives a syntax error when attempting this.
Should I add a foo value to the table, or is there a better way to do this in SQ Lite?
-- edit --
The following queries give a syntax error:
INSERT INTO Q_GROUP VALUES;
INSERT INTO Q_GROUP VALUES ();
INSERT INTO Q_GROUP () VALUES ();
INSERT INTO Q_GROUP ;
try like this,
insert into Q_GROUP values(1);
Use null as placeholder
insert into Q_GROUP (Id)
values (null);
SQLFiddle demo
To insert the default values in all columns, use:
INSERT INTO Q_GROUP DEFAULT VALUES;
For instance:
{create table Participant ( id serial, primary key(id) );}
How do you insert into table in this case?
If you create the table like above,
You can use default in following way to insert:
INSERT INTO Participant values(default);
Check out SQLFIDDLE.
Another way to insert is:
INSERT INTO Participant values(NEXTVAL('Participant_id_seq'));
CREATE TABLE will create implicit sequence "Participant_id_seq" for serial column "Participant.id".
You can get the sequence for the table using pg_get_serial_sequence function in following way:
pg_get_serial_sequence('Participant', 'id')
It will take new value from sequence using NEXTVAL().
Check out SQLFIDDLE
insert into Participant values (default);