Reputation: 9305
I have to get a value from a select and create a variable to use in a insert, is it possible in PostgreSQL? I can't create a function because my hosting don't allow this.
Here is the table creation schema:
CREATE SEQUENCE identificador_produto START 1;
CREATE TABLE product (
id integer DEFAULT nextval('identificador_produto') primary key,
description varchar(60) not null
);
CREATE TABLE material (
product_id integer DEFAULT nextval('identificador_produto') primary key,
description varchar(60) not null
);
Example to ilustrate what i need:
begin;
select currval('identificador_produto') as id;
insert into material (product_id, description) values (id, 'Gold');
insert into material (product_id, description) values (id, 'Silver');
insert into material (product_id, description) values (id, 'Wood');
insert into material (product_id, description) values (id, 'Steel');
insert into material (product_id, description) values (id, 'Water');
insert into material (product_id, description) values (id, 'Paper');
commit;
I have to assign the 'id' value to a variable and them use it to do some inserts in the same transaction, but the inserts share the same sequence of 'product', because of this i can't use the curval() function, otherwise each insert will get a different id.
Can anybody help me?
Upvotes: 1
Views: 8031
Reputation:
First I think your understanding of currval
is wrong. currval
will return the last generated id that was taken from your sequence.
The following will insert all rows with the same id:
insert into material (product_id, description)
values (nextval('identificador_produto'), 'Gold');
insert into material
(product_id, description)
values
(currval('identificador_produto'), 'Silver');
insert into material
(product_id, description)
values
(currval('identificador_produto'), 'Wood');
insert into material
(product_id, description)
values
(currval('identificador_produto'), 'Steel');
insert into material
(product_id, description)
values
(currval('identificador_produto'), 'Water');
insert into material
(product_id, description)
values
(currval('identificador_produto'), 'Paper');
The first one generates a new ID and the subsequent INSERT
s re-use that same id. This is transaction safe and will work correctly even when thousands of connections do this (that's the beauty of sequences)
But I think your table design is wrong. The way you defined the tables, you could just move the description column to the product table.
My guess is that you actually want something like this:
CREATE SEQUENCE identificador_produto START 1;
CREATE TABLE product (
id integer DEFAULT nextval('identificador_produto') primary key,
description varchar(60) not null
);
CREATE TABLE material (
material_id serial primary key,
product_id integer not null
references product(id),
description varchar(60) not null
);
Which means you have one or more rows in material that reference a specific product. The insert pattern would then look something like this:
insert into product
(description)
values
('foobar');
insert into material
(product_id, description)
values
(currval('identificador_produto'), 'silver');
insert into material
(product_id, description)
values
(currval('identificador_produto'), 'gold');
Upvotes: 4
Reputation: 19471
If you're looking to do both inserts with the same id value, in the same transaction, this might be a good alternative:
WITH x(descr) AS (VALUES ('Gold'), ('Silver'))
INSERT INTO material (product_id, description)
SELECT id, descr
FROM x,
(SELECT id FROM product WHERE condition = 100) y;
The other possibility, if you really need imperative code with variables, is a DO construct:
http://www.postgresql.org/docs/current/interactive/sql-do.html
Upvotes: 2
Reputation: 125254
You don't need a variable for that:
insert into material (product_id, description) values (
(select id from product where condition = 100)
, 'Gold');
Upvotes: 2
Reputation: 1341
Yeah, first declare a variable in the declare section.
Then say "select id into variable from product where condition = 100;" and continue
declare
myvar int;
begin
select id into myvar from product where condition = 100;
...
end;
Upvotes: 1