我在(Postgre)sql中熟悉了触发器。
我现在拥有的是一张Verine桌子(这是德语的团队)。
Vereine :{[team:string, punkte:int, serie:int]}
这是我写的非常小的东西,只是为了了解如何创建表,对内容和视图进行排序,现在我将其用于触发器。无论如何,团队显然是团队的名称和主键,朋克表示积分,意甲是指团队的划分(只是为了您了解不同域的含义)。
问题从这里开始:
因此,假设我有一个团队,比如说“尤文图斯”,已经在我的表“ Vereine”中。如果我然后要插入具有相同键“尤文图斯”的另一行/元组,而不是想要两个条目/元组,我想更新键“尤文图斯”的值(用旧值替换新值) 。在下面的示例中,我尝试使用积分进行操作。
create table vereine(
team varchar(20) primary key,
punkte int not null,
serie int not null
)
--beispiel was die Aufgabe verlangt
create trigger prevent_redundancy
before insert on vereine
for each row
execute procedure update_points()
create or replace function update_points()
returns trigger as
$BODY$
begin
if (new.team in (old.team)) then
update vereine
set punkte = new.punkte
where team = new.team;
else
end if;
end;
$BODY$
LANGUAGE plpgsql;
--Was die aufgabe verlangt ist, dass keine bereits existierende ID eingefügt wird,
--sondern der entsprechende Modellname dann umgeändert wird
insert into vereine values('JuventusFC', 50, 1);
insert into vereine values('AS Roma', 30, 1);
insert into vereine values('ParmaCalcio1913', 25, 1);
insert into vereine values('Palermo', 37, 2);
insert into vereine values('Pescara', 32, 2);
insert into vereine values('Spezia', 26, 2);
insert into vereine values('Carrarese Calcio', 34, 3);
insert into vereine values('Virtus Entella', 31, 3);
insert into vereine values('Juventus U-23', 50, 3);
select *
from vereine
insert into vereine values('JuventusFC', 53, 1);
这是我的问题:
首先:如何检查表中是否已存在键?在查询中,我会使用情况,何时何地或只是以不同方式处理问题的情况。我需要if语句吗?换句话说,您将如何重写
if (new.team in (old.team)) then
以便检查它是否已经存在?
第二:这可能与第一个问题有关:尝试插入任何元组时,我会得到此信息:
Query execution failed
Reason:
SQL Error [54001]: ERROR: stack depth limit exceeded
Hint: Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate.
Where: SQL statement "insert into vereine values(new.team, new.punkte, new.serie)"
如何修复我的代码,使其能够执行我想要的工作?
抱歉,太罗word了。我只想确保您了解这应该如何工作。是的,我之前曾问过一个与同一作业相关的问题,但这是一个完全不同的问题。也很抱歉。
答案 0 :(得分:0)
您基本上想要的是UPSERT
语法,如this answer所示,使用UNIQUE CONSTRAINT
列上的team
。我建议您将其用于相关功能的插入操作中,而不要使用触发器。
如果您仍然坚持使用触发器,则可以编写如下内容。
create or replace function update_points()
returns trigger as
$BODY$
begin
if EXISTS (select 1 FROM vereine WHERE team = new.team ) then
update vereine
set punkte = new.punkte
where team = new.team;
RETURN NULL;
else
RETURN NEW;
end if;
end;
$BODY$
LANGUAGE plpgsql;
在触发器返回过程中,RETURN NULL;
和RETURN NEW;
与Before Insert
触发器之间的区别是RETURN NULL
不会执行触发语句(即主{{ 1}}操作),而INSERT
继续正常执行预期的RETURN NEW;
语句。
现在,您遇到了错误INSERT
,
看来您已经在表上创建了另一个由更新操作触发的触发器,或者您已经写了另一个插入并从该触发器返回SQL Error [54001]: ERROR: stack depth limit exceeded
。您必须就如何处理它是否是另一个触发器(删除它或修改它)进行电话咨询,但这超出了此问题的范围,如果您还有其他问题,则应单独询问)
您可以通过简单地查询NEW
或information_schema.triggers
来检查表上是否存在触发器,有关更多详细信息,请参考this answer。