加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

PostgreSQL序列基于另一列

发布时间:2020-12-13 16:40:36 所属栏目:百科 来源:网络整理
导读:让我说我有一张桌子: Column | Type | Notes---------+------------ +---------------------------------------------------------- id | integer | An ID that's FK to some other table seq | integer | Each ID gets it's own seq number data | text |
让我说我有一张桌子:
Column   |     Type    |                        Notes
---------+------------ +----------------------------------------------------------
 id      | integer     | An ID that's FK to some other table
 seq     | integer     | Each ID gets it's own seq number
 data    | text        | Just some text,totally irrelevant.

id seq是组合键。

我想看到的是:

ID  | SEQ   |                        DATA
----+------ +----------------------------------------------
 1  | 1     | Quick brown fox,lorem ipsum,lazy dog,etc etc.
 1  | 2     | Quick brown fox,etc etc.
 1  | 3     | Quick brown fox,etc etc.
 1  | 4     | Quick brown fox,etc etc.
 2  | 1     | Quick brown fox,etc etc.
 3  | 1     | Quick brown fox,etc etc.
 3  | 2     | Quick brown fox,etc etc.
 3  | 3     | Quick brown fox,etc etc.
 3  | 4     | Quick brown fox,etc etc.

如你所见,id和seq的组合是唯一的。

我不知道如何设置我的表(或插入语句?)来做到这一点。我想插入id和数据,导致seq是依赖于id的子序列。

没问题!我们要做两个表,东西和东西。东西将是您在问题中描述的表,事情是它所指的:
CREATE TABLE things (
    id serial primary key,name text
);

CREATE TABLE stuff (
    id integer references things,seq integer NOT NULL,notes text,primary key (id,seq)
);

然后,我们将使用一个触发器来设置,每次创建一个行时都会创建一个新的序列:

CREATE FUNCTION make_thing_seq() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
begin
  execute format('create sequence thing_seq_%s',NEW.id);
  return NEW;
end
$$;

CREATE TRIGGER make_thing_seq AFTER INSERT ON things FOR EACH ROW EXECUTE PROCEDURE make_thing_seq();

现在我们最终会得到thing_seq_1,thing_seq_2等等

现在,另外一个触发器的东西,以便它每次使用正确的顺序:

CREATE FUNCTION fill_in_stuff_seq() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
begin
  NEW.seq := nextval('thing_seq_' || NEW.id);
  RETURN NEW;
end
$$;

CREATE TRIGGER fill_in_stuff_seq BEFORE INSERT ON stuff FOR EACH ROW EXECUTE PROCEDURE fill_in_stuff_seq();

这将确保当行进入填充时,id列用于查找正确的序列来调用nextval。

这是一个示范:

test=# insert into things (name) values ('Joe');
INSERT 0 1
test=# insert into things (name) values ('Bob');
INSERT 0 1
test=# select * from things;
 id | name
----+------
  1 | Joe
  2 | Bob
(2 rows)

test=# d
              List of relations
 Schema |     Name      |   Type   |  Owner
--------+---------------+----------+----------
 public | stuff         | table    | jkominek
 public | thing_seq_1   | sequence | jkominek
 public | thing_seq_2   | sequence | jkominek
 public | things        | table    | jkominek
 public | things_id_seq | sequence | jkominek
(5 rows)

test=# insert into stuff (id,notes) values (1,'Keychain');
INSERT 0 1
test=# insert into stuff (id,'Pet goat');
INSERT 0 1
test=# insert into stuff (id,notes) values (2,'Family photo');
INSERT 0 1
test=# insert into stuff (id,'Redundant lawnmower');
INSERT 0 1
test=# select * from stuff;
 id | seq |        notes
----+-----+---------------------
  1 |   1 | Keychain
  1 |   2 | Pet goat
  2 |   1 | Family photo
  1 |   3 | Redundant lawnmower
(4 rows)

test=#

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读