2017-02-21 61 views
0

我有一个PostgreSQL数据库版本9.5.0。非主键POSTGRES序列触发器

UserComments创建这样的:

create table UserComments ( 
    userId integer, 
    commentNr integer, 
    comment text, 
    UNIQUE (userId, commentNr) 
); 

表不能更改无论是我可以添加额外的表。

我想根据userId条目的数量在commentNr上创建一个序列(换句话说:自动递增值)。 对于每个新条目具有相同的userId其值应递增。
例子:

 
userId | commentNr | comment 
-------|-----------|--------- 
1  | 1  | blabla 
1  | 2  | more bla 
2  | 1  | myownbla 
1  | 3  | evenmorebla 

我已经找到了一些答案与“触发器”和“窗口函数”,但因为我不能改变表并没有真正为我工作。 最好的解决办法是在每INSERT触发自动counts /计算commentNr这样我就可以

insert into user(userId, comment) values ('1', 'bla'); 

任何帮助增加新的项目,将不胜感激。

+0

'主键(id),'::你的表中没有列'id'。请发布真实的代码。 – joop

+0

你是对的 - 主键对于这个例子来说是不需要的。 –

回答

0

指定要自动计算commentNr场,你可以使用TRIGGER:

CREATE INDEX i1 ON UserComments (userId, commentNr DESC); 

CREATE OR REPLACE FUNCTION set_commentNr() RETURNS TRIGGER AS $sql$ 
BEGIN 
    NEW.commentNr = coalesce(max(commentNr) + 1, 1) FROM UserComments WHERE UserId = NEW.userID; 
    RETURN NEW; 
END; 
$sql$ LANGUAGE plpgsql STABLE; 


CREATE TRIGGER ins_comment BEFORE INSERT ON UserComments FOR EACH ROW EXECUTE PROCEDURE set_commentNr(); 

小测试:

insert into userComments (userId, comment) values ('1', 'bla'); 
insert into userComments (userId, comment) values ('1', 'bla'); 
insert into userComments (userId, comment) values ('2', 'bla'); 
insert into userComments (userId, comment) values ('1', 'bla'); 
insert into userComments (userId, comment) values ('2', 'bla'); 

SELECT * FROM userComments; 

userid | commentnr | comment 
--------+-----------+--------- 
     1 |   1 | bla 
     1 |   2 | bla 
     2 |   1 | bla 
     1 |   3 | bla 
     2 |   2 | bla 
(5 rows) 

创建索引i1以提高计算下一个值的性能:

               QUERY PLAN                
------------------------------------------------------------------------------------------------------------------------------------- 
Result (cost=4.17..4.18 rows=1 width=4) (actual time=0.032..0.032 rows=1 loops=1) 
    InitPlan 1 (returns $0) 
    -> Limit (cost=0.15..4.17 rows=1 width=4) (actual time=0.026..0.026 rows=1 loops=1) 
      -> Index Only Scan using i1 on usercomments (cost=0.15..24.27 rows=6 width=4) (actual time=0.021..0.021 rows=1 loops=1) 
       Index Cond: ((userid = 1) AND (commentnr IS NOT NULL)) 
       Heap Fetches: 1 
Planning time: 0.238 ms 
Execution time: 0.095 ms 
0

对于这样的简单情况,不需要创建触发器。可以在CTE或子查询中计算正确的顺序并插入。

注意:如果使用下面的SQL,插入的userId有两次

INSERT INTO "user" ("userId", "commentNr", "comment") (
WITH 
    nextval AS (
    SELECT COALESCE(MAX("commentNr"),0)+1 commentNr 
    FROM "user" 
    WHERE "userId" = '1' 
) 
SELECT '1', nextval.commentNr, 'bla' 
FROM nextval 
);