Mar*_*usz 6 database postgresql
我有两个表:
CREATE TABLE "user"
(
username character varying(35) NOT NULL,
CONSTRAINT user_pk PRIMARY KEY (username)
)
CREATE TABLE item
(
id serial NOT NULL,
username character varying(35),
user_item_number integer,
item_value character varying(35),
CONSTRAINT item_pk PRIMARY KEY (id),
CONSTRAINT item_fk FOREIGN KEY (username)
REFERENCES "user" (username) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT unique_item_username UNIQUE (username, user_item_number)
)
Run Code Online (Sandbox Code Playgroud)

我想user_item_number分别为每个自动增加username。下图显示了示例。对于每个username:(user1,user2)user_item_number从1开始并递增1。

我想,我应该插入其中得到的最大值之前使用一些触发user_item_number的username,其插入并加一。但是我不知道如何编写触发器。
我也不知道如何考虑并发访问(并发插入多个具有相同值的行username)。当插入两行相同的行username并user_item_number插入时,我不想收到约束违反错误,我希望该触发器捕获该错误并再次增加 user_item_number值。
任何的想法?
我找到了解决方案。我写了触发器和过程:
create OR REPLACE function myinsert() RETURNS trigger as $$
BEGIN
if NEW.user_item_number is not null then return NEW;
end if;
loop
<<roolbac_to>>
declare
max INTEGER:=null;
begin
SELECT count(user_item_number) into max from item where username=NEW.username;
if max is null then
max:=1;
ELSE
max=max+1;
end if;
INSERT INTO item( username, user_item_number, item_value) VALUES (NEW.username,max, NEW.item_value);
exit;
exception WHEN unique_violation THEN
--do nothing
end;
end loop;
return null;
end;
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER trig1
before insert
ON item
FOR EACH ROW
EXECUTE PROCEDURE myinsert();
Run Code Online (Sandbox Code Playgroud)
这个解决方案允许创建间隙,但对我来说没问题。
我想使用触发器而不是插入,但这是不可能的。所以我在插入触发器之前做了并返回null。插入是在过程内部执行的。操作说明:
if NEW.user_item_number is not null then return NEW;
end if;
Run Code Online (Sandbox Code Playgroud)
就是不允许再次发生
| 归档时间: |
|
| 查看次数: |
675 次 |
| 最近记录: |