插入后需要创建一个触发器来增加表中的值

时间:2019-07-05 09:10:41

标签: postgresql triggers

我当前正在使用的当前游戏数据库原型上的触发器存在问题

所以,我有这两个表

CREATE TABLE public.hunters
(   id integer NOT NULL,
    name character varying(30) COLLATE pg_catalog."default" NOT NULL,
    weapon character varying(30) COLLATE pg_catalog."default" NOT NULL,
    ranking character varying(30) COLLATE pg_catalog."default" NOT NULL,
    nhunts integer NOT NULL,
    sex character(1) COLLATE pg_catalog."default" NOT NULL,
    title character varying(30) COLLATE pg_catalog."default",
)

CREATE TABLE public.hunts
(
    id_h integer NOT NULL,
    id_m integer NOT NULL,
    id_l integer NOT NULL,
    code integer NOT NULL,
    huntname character varying(50) COLLATE pg_catalog."default",
)

还有其他表,但是问题围绕着这两个表。

看,狩猎是一个表格,其中包含猎人的ID,要狩猎的怪物以及将被狩猎的怪物的位置-以及que hunt quest的名称。每次猎人打猎一些怪物时,应该在桌子上的猎人身上增加“ nhunts”值。

许多猎人可能在许多不同的地方猎杀许多不同的怪物。代码列是一个序数值,代表一次狩猎的历史性(例如,如果代码等于20,那么这是自“曾经”以来的第20次狩猎,或者至少是自首次注册以来的20次狩猎)。

问题是我不知道如何创建此触发器。我尝试了一切,但价值从未更新

这是我尝试过的。但这只是不更新​​任何内容

CREATE OR REPLACE FUNCTION Hunter_HuntsIncrement() RETURNS TRIGGER AS $$
DECLARE
    idv integer;
BEGIN
    idv := TG_ARGV[0];  
    IF (new.id_h = old.id_h AND new.code = old.code) THEN
        UPDATE hunters
            SET nhunts = nhunts + 1
        WHERE id = idv;
    END if;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER updating_nhunts AFTER INSERT ON hunts
FOR EACH STATEMENT EXECUTE PROCEDURE hunter_huntsincrement()

我知道这可能是非常错误的,但是我是触发器的新手,我真的很想在这里伸出援手

1 个答案:

答案 0 :(得分:0)

维护摘要值非常棘手-容易deadlock创建程序。

如果您真的必须这样做,因为您知道否则会遇到性能问题(例如成百上千的nhunt),那么最好为nhunt创建一个单独的摘要表,例如:

ISERROR

狩猎触发器:

  • 为每个添加,删除,更新的行运行;
  • 在每个插入项上添加一行FALSE
  • 在每次删除操作中添加一行<div> <form [formGroup]="addressData" (ngSubmit)="getAddress()"> <input class="addressBar" [formControl]=addressData.controls.address type="text" placeholder="Address" maxlength="30" autofocus> <br><br><button class="searchBtn" type="submit">Search</button> </form> </div>
  • 以上两项均更改了CREATE TABLE hunts_summary ( id_hs bigserial primary key, id_h integer NOT NULL, nhunts integer NOT NULL ); CREATE INDEX hunts_summary_id_h_idx on hunts_summary(id_h);

由于触发器只会添加新行,因此不会锁定现有行,因此不会死锁。

但这还不够-如上所述,摘要表将使行增长的速度比寻线表快或快,因此它并不是很有用。因此,我们需要添加某种方式来定期合并现有行-某些改变方式:

(id_h, nhunts) = (NEW.id_h, 1)

收件人:

(id_h, nhunts) = (OLD.id_h, -1)

此操作不应在每次触发调用时都运行,因为这样做会很慢,但可以随机运行-例如,随机每1/1024次调用。此功能将使用“跳过锁定”关键字来避免触摸已锁定的行,避免否则可能出现死锁。

这种触发器看起来像这样:

id_h

触发器在笔记本电脑上足够快地运行,可以在45秒内插入1M行以搜寻表。

下面的视图将使从摘要中提取当前nhunt变得容易。即使搜寻表将达到数十亿,查询它也会花费很少的时间或毫秒:

id_h nhunts
1    1
1    1
2    1
2    -1
1    1
1    -1
2    1
1    1
2    1