PostgreSQL序列基于另一列

前端之家收集整理的这篇文章主要介绍了PostgreSQL序列基于另一列前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
让我说我有一张桌子:
  1. Column | Type | Notes
  2. ---------+------------ +----------------------------------------------------------
  3. id | integer | An ID that's FK to some other table
  4. seq | integer | Each ID gets it's own seq number
  5. data | text | Just some text,totally irrelevant.

id seq是组合键。

我想看到的是:

  1. ID | SEQ | DATA
  2. ----+------ +----------------------------------------------
  3. 1 | 1 | Quick brown fox,lorem ipsum,lazy dog,etc etc.
  4. 1 | 2 | Quick brown fox,etc etc.
  5. 1 | 3 | Quick brown fox,etc etc.
  6. 1 | 4 | Quick brown fox,etc etc.
  7. 2 | 1 | Quick brown fox,etc etc.
  8. 3 | 1 | Quick brown fox,etc etc.
  9. 3 | 2 | Quick brown fox,etc etc.
  10. 3 | 3 | Quick brown fox,etc etc.
  11. 3 | 4 | Quick brown fox,etc etc.

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

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

没问题!我们要做两个表,东西和东西。东西将是您在问题中描述的表,事情是它所指的:
  1. CREATE TABLE things (
  2. id serial primary key,name text
  3. );
  4.  
  5. CREATE TABLE stuff (
  6. id integer references things,seq integer NOT NULL,notes text,primary key (id,seq)
  7. );

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

  1. CREATE FUNCTION make_thing_seq() RETURNS trigger
  2. LANGUAGE plpgsql
  3. AS $$
  4. begin
  5. execute format('create sequence thing_seq_%s',NEW.id);
  6. return NEW;
  7. end
  8. $$;
  9.  
  10. CREATE TRIGGER make_thing_seq AFTER INSERT ON things FOR EACH ROW EXECUTE PROCEDURE make_thing_seq();

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

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

  1. CREATE FUNCTION fill_in_stuff_seq() RETURNS trigger
  2. LANGUAGE plpgsql
  3. AS $$
  4. begin
  5. NEW.seq := nextval('thing_seq_' || NEW.id);
  6. RETURN NEW;
  7. end
  8. $$;
  9.  
  10. CREATE TRIGGER fill_in_stuff_seq BEFORE INSERT ON stuff FOR EACH ROW EXECUTE PROCEDURE fill_in_stuff_seq();

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

这是一个示范:

  1. test=# insert into things (name) values ('Joe');
  2. INSERT 0 1
  3. test=# insert into things (name) values ('Bob');
  4. INSERT 0 1
  5. test=# select * from things;
  6. id | name
  7. ----+------
  8. 1 | Joe
  9. 2 | Bob
  10. (2 rows)
  11.  
  12. test=# \d
  13. List of relations
  14. Schema | Name | Type | Owner
  15. --------+---------------+----------+----------
  16. public | stuff | table | jkominek
  17. public | thing_seq_1 | sequence | jkominek
  18. public | thing_seq_2 | sequence | jkominek
  19. public | things | table | jkominek
  20. public | things_id_seq | sequence | jkominek
  21. (5 rows)
  22.  
  23. test=# insert into stuff (id,notes) values (1,'Keychain');
  24. INSERT 0 1
  25. test=# insert into stuff (id,'Pet goat');
  26. INSERT 0 1
  27. test=# insert into stuff (id,notes) values (2,'Family photo');
  28. INSERT 0 1
  29. test=# insert into stuff (id,'Redundant lawnmower');
  30. INSERT 0 1
  31. test=# select * from stuff;
  32. id | seq | notes
  33. ----+-----+---------------------
  34. 1 | 1 | Keychain
  35. 1 | 2 | Pet goat
  36. 2 | 1 | Family photo
  37. 1 | 3 | Redundant lawnmower
  38. (4 rows)
  39.  
  40. test=#

猜你在找的Postgre SQL相关文章