0

我必须从选择中获取一个值并创建一个要在插入中使用的变量,在 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”值分配给一个变量,他们使用它在同一个事务中进行一些插入,但是插入共享相同的“产品”序列,因此我不能使用 curval() 函数,否则每个插入将获得不同的 id。

有谁能够帮助我?

4

4 回答 4

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的 s 重新使用相同的 id。这是交易安全的,即使有数千个连接这样做也能正常工作(这就是序列的美妙之处)

但我认为你的桌子设计是错误的。您定义表的方式,您可以将描述列移动到产品表。

我的猜测是你实际上想要这样的东西:

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');
于 2012-04-27T07:30:24.783 回答
2

你不需要一个变量:

insert into material (product_id, description) values (
    (select id from product where condition = 100)
    , 'Gold');
于 2012-04-26T19:25:35.457 回答
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

于 2012-04-26T19:46:04.083 回答
1

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

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

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

    ...
    end;
于 2012-04-26T18:37:50.357 回答