是否可以在PostgreSQL中为变量分配一个select字段?

时间:2012-04-26 18:36:15

标签: sql postgresql select variable-assignment

我必须从select中获取一个值并创建一个要在插入中使用的变量,是否可以在PostgreSQL中使用?我无法创建一个函数,因为我的托管不允许这样做。

这是表创建模式:

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
);

说明我需要的例子:

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;

我必须将'id'值分配给变量,并且他们使用它在同一个事务中执行一些插入,但是插入共享相同的'product'序列,因此我无法使用curval ()函数,否则每个插入将获得不同的id。

有人能帮助我吗?

4 个答案:

答案 0 :(得分:3)

首先,我认为您对currval的理解是错误的。 currval将返回从序列中获取的最后一个生成的 ID。

以下内容将插入具有相同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');

第一个生成 ID,后续INSERT重新使用相同ID 。这是交易安全的,即使成千上万的连接这样做(这是序列之美)也能正常工作

但我觉得你的桌面设计错了。您定义表的方式,您只需将description列移动到product表。

我的猜测是你真的想要这样的东西:

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
);

这意味着您在材料中有一行或多行引用特定产品。插入模式看起来像这样:

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');

答案 1 :(得分:2)

您不需要变量:

insert into material (product_id, description) values (
    (select id from product where condition = 100)
    , 'Gold');

答案 2 :(得分:2)

如果您希望在同一事务中执行两个具有相同id值的插入,这可能是一个不错的选择:

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;

另一种可能性,如果你真的需要带变量的命令式代码,那就是DO构造:

http://www.postgresql.org/docs/current/interactive/sql-do.html

答案 3 :(得分:1)

是的,首先在声明部分声明一个变量。

然后说“从条件= 100的产品中选择id到变量;”并继续

    declare
    myvar int;
    begin
    select id into myvar from product where condition = 100;

    ...
    end;