我有一个简单的表,主键,时间戳和&计数。
我有触发器来自动更新时间戳&在更新事件之前计数是标准的。
要执行触发器,我必须执行一个事件(例如更新)。虽然它可以执行标准更新,但我并不完全熟悉它,因为它似乎是多余的。
update users set username = 'johndoe' where username = 'johndoe';
从SQL角度来看,显式更新字段会感觉更好,但我宁愿将自动更新保留给触发器,以便将代码库与模式实现完美分离(以便以后升级)。
有没有办法在不使用更新的情况下启动表行上的所有关联触发器?或者这是一个好的解决方案吗?未来的数据库更新是否会拒绝该事务,因为没有任何变化?
谢谢!
/* update_timestamp function to call from trigger */
create function update_timestamp() returns trigger as $$
begin
NEW.timestamp := current_timestamp;
return NEW;
end;
$$ language plpgsql;
/* update_count function to call from trigger */
create function update_count() returns trigger as $$
begin
NEW.count := OLD.count + 1;
return NEW;
end;
$$ language plpgsql;
/* users table */
create table users(
username character varying(50) not null,
timestamp timestamp not null default current_timestamp,
count bigint not null default 1);
/* timestamp & count triggers */
create trigger users_timestamp_upd before update on users for each row execute procedure update_timestamp();
create trigger users_count_upd before update on users for each row execute procedure update_count();
答案 0 :(得分:0)
最后一个问题:
未来的数据库更新是否会拒绝该事务,因为没有任何变化?
没有。这是完全有效的SQL语法。拒绝它将在SQL标准支持中倒退,这对于任何生产就绪的RDBMS来说都是非常不规则的。此外,该标准要求BEFORE UPDATE
触发器在所有受影响的行上运行,即使行实际上没有更改。
有没有办法在不使用更新的情况下启动表行上的所有关联触发器?或者这是一个好的解决方案吗?
这是一个合理的解决方案,但我称之为代码味道。通常,触发器不是关系型的。纯粹的关系数据库更容易推理。在纯粹的关系数据库中,你不会做这样的事情。所以你应该问问自己,触发器是否是一个好主意。当然,答案可能是“是的,因为没有其他合理的方法可以做到这一点。”但你应该考虑它,而不是假设情况就是这样。
答案 1 :(得分:0)
感谢。决定使用函数而不是触发器。直接从PHP调用它。
create or replace function add_update_user(varchar) returns void as $$
begin
if exists (select 1 from users where username = $1) then
update users set timestamp = current_timestamp where username = $1;
update users set count = count + 1 where username = $1;
else
insert into users (username) values ($1);
end if;
end;
$$ language plpgsql;
create table users(
username character varying(50) not null,
timestamp timestamp not null default current_timestamp,
count bigint not null default 1);
select add_update_user('testusername');