出于一致性原因,我想使关系中的列不可修改。
背景故事是我有一个:n 关系,其中“连接”关系具有附加值。我不希望任何人能够更改关系伙伴的 ID。
到目前为止我想出了什么:
创建一个触发器来检查 NEW 值是否与 OLD 值相同。但如果条件证明为 TRUE,我不知道如何拒绝 UPDATE 操作。
到目前为止,这是我的触发器:
CREATE TRIGGER deny_nton_change BEFORE UPDATE ON Schueler_in_Klasse
FOR EACH ROW BEGIN
IF NEW.Schueler_ID != OLD.Schueler_ID OR NEW.Klasse_ID != OLD.Klasse_ID THEN
END IF;
END;
Run Code Online (Sandbox Code Playgroud) 是否可以暂时禁用触发器,但仅针对一张表。
例如,我有一个表,带有插入、更新和删除触发器的 TableA。我也有一个具有相同触发器的表 B,但它们只影响表 A 中的某些列。
我现在有一个使用两个表的更新查询。我知道表 A 中的更新需要触发触发器,但表 B 中的更新绝对不需要触发触发器。所以我想禁用这些触发器,直到更新完成。
这可能吗?我正在使用 MySQL 5.1
[附录]
这是一个触发器表A本质上
BEGIN
IF (OLD.status != 1 AND NEW.status = 2) THEN
IF (OLD.geo_lat IS NOT NULL AND OLD.geo_long IS NOT NULL) THEN
DELETE FROM geo WHERE datatype IN (3,4) AND foreignid = NEW.id;
END IF;
ELSEIF (OLD.Status = 1 AND NEW.Status != 2) THEN
IF (NEW.geo_lat IS NOT NULL AND NEW.geo_long IS NOT NULL) THEN
INSERT INTO geo (datatype, foreignid, long, lat, hostid, morton, status) …Run Code Online (Sandbox Code Playgroud) 我正在尝试检查什么事件称为我的触发器,例如INSERT,UPDATE或DELETE。
Oracle 触发器可以在一个简单的“IF”语句中进行检查:
IF INSERTING, IF UPDATING or even IF DELETING
Run Code Online (Sandbox Code Playgroud)
PostgreSQL 上有类似的说法吗?
通常我只是创建一个函数 for INSERT,另一个 forUPDATE和一个 for DELETE,但如果有某种方法只创建一个函数,那就浪费了代码。
有人可以帮忙吗?
我在 PostgreSql 9.1 中有一个触发器,我想在插入多个表时触发它。是否可以让它影响所有这些表而不是为所有这些表创建触发器?我有 58 个表,我想使用调用触发器函数的同一个插入触发器,所以我一直在使用
create trigger tuweke
after insert on product
for each row execute procedure tuwekeAdjustextract();
create trigger tuweke
after insert on caneweightment
for each row execute procedure tuwekeAdjustextract();
...
Run Code Online (Sandbox Code Playgroud)
对所有这些表都这样做,然后我们有多个模式,所以工作量很大,这可以在一个查询中完成吗?然后影响该模式或整个数据库中的所有表?
我有一个带有 SQL Server 托管数据库的应用程序。我无权访问应用程序代码,但我可以完全访问数据库。我已将自己的自定义审计添加到表中以帮助调试。
我正在使用after触发器。以下是我的触发器的简化版本。
问题:我看到update在相应insert审计记录之前的审计记录。这怎么可能?差异只有几毫秒,对于我目前的目的并不重要,但我可以想象更糟糕的情况,其中程序逻辑取决于正确的年表。
我知道在相同类型的触发器(全部insert或全部update)之间控制触发器执行顺序的方法。我可以对异构触发器执行顺序做出哪些假设?
create trigger dbo.MyTrigger_i on dbo.theTable
after insert
as
begin
set nocount on
declare @Date datetime, @User sysname
set @Date = GETDATE()
set @User = SUSER_SNAME()
insert into MyAudit (RowID, [Date], UserName, Comment)
select i.ID, @Date, @User, 'Insert'
from
inserted as i
end
go
create trigger dbo.MyTrigger_u on dbo.theTable
after update
as
begin
set nocount on
declare @Date datetime, @User sysname
set @Date …Run Code Online (Sandbox Code Playgroud) 我在 x86_64-unknown-linux-gnu 上的 PostgreSQL 9.4.3 中的表和触发器,由 gcc (Debian 4.9.2-10) 4.9.2,64 位编译:
CREATE TABLE measurements (
measurement_id SERIAL PRIMARY KEY NOT NULL,
measurement_size_in_bytes INTEGER NOT NULL
);
CREATE TABLE file_headers (
header_id SERIAL PRIMARY KEY NOT NULL,
measurement_id INTEGER NOT NULL,
file_header_index_start INTEGER,
file_header_index_end INTEGER
);
CREATE TRIGGER measurement_ids AFTER INSERT
ON measurements FOR EACH ROW
EXECUTE PROCEDURE ins_function('SELECT measurement_id FROM measurements
ORDER BY measurement_id desc limit 1;', 1, 666 );
Run Code Online (Sandbox Code Playgroud)
在那里我假设 SELECT 的数据类型自 SERIAL 以来是 INTEGER 但它显然是错误的,因为我从这个启动触发器的命令中收到错误消息:
INSERT INTO measurements …Run Code Online (Sandbox Code Playgroud) 这个答案向我提出了如何在这样的函数之间VALUES和SELECT中进行选择的问题。在 x86_64-unknown-linux-gnu 上使用PostgreSQL 9.4.3,由 gcc (Debian 4.9.2-10) 4.9.2, 64-bit 编译:
CREATE OR REPLACE FUNCTION insaft_function()
RETURNS TRIGGER AS
$func$
BEGIN
INSERT INTO file_headers (measurement_id, file_header_index_start
, file_header_index_end)
VALUES (NEW.measurement_id, TG_ARGV[0]::int, TG_ARGV[1]::int);
RETURN NULL; -- result ignored since this is an AFTER trigger
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
VALUES处理多行,但SELECT你可以做更多的事情。这里唯一的要求是对INSERT表格执行上述操作。您可以假设INSERT在系统的持续质量保证中每个周期完成100k 次这样的操作。
我注意到这些差异与我的数据不同,这里选择了三个中值:
VALUES
real user sys
-------------------------------
0m0.353s 0m0.256s 0m0.028s
0m0.327s 0m0.252s 0m0.036s
0m0.358s …Run Code Online (Sandbox Code Playgroud) postgresql trigger performance select postgresql-performance
我有触发器和一个存储过程(所以 SP 在触发器运行时运行)。我需要一个函数来找到下一个星期六放入 SP。
所以让我们说,今天是星期三(2015-7-22)。如果我的触发器今天运行,其中的 SP 必须找到下一个星期六 (2015-7-25)。
另外,即使是星期六,但时间早于晚上 9.30,它也必须找到当天。晚上 9.30 之后,它必须在下周六返回。
我想把我的整个触发器和 sp 放在这里,但我不想在这里拥挤。我只需要想法,谢谢。
编辑:
感谢 oNaye,我编写了以下代码:
CREATE DEFINER=`root`@`localhost` PROCEDURE `newGuess`(
IN `muserID` INT,
IN `numm1` INT,
IN `numm2` INT,
IN `numm3` INT,
IN `numm4` INT,
IN `numm5` INT,
IN `numm6` INT)
begin
set @today = (select weekday(curdate())+1); /*monday is the first day in here*/
if @today<6 or @today=7 then /*it is NOT saturday*/
set @nextSaturday = (SELECT DATE_ADD(NOW(),INTERVAL IF(WEEKDAY(NOW())>=5,(6-WEEKDAY(NOW())),(5-WEEKDAY(NOW()))) DAY));
end if;
if @today = 6 then /* …Run Code Online (Sandbox Code Playgroud) 我想向 PG 添加一些审计触发器,以记录对表的所有更改。我找到了一个示例触发器(wiki.postgresql.com - 9.1+ 审计触发器),它让我开始了。
我想要做的是自动传递一些附加数据,例如 theuser-id或 other 键,以便触发器可以将更改链接回进行更改的应用程序用户。基本流程如下:
set conn_context = {userid};)使用 MS SQL 时,我能够通过执行SET CONTEXT_INFO ...data.... 我希望有一种方法可以为 PG 做到这一点;我还没有找到,但这可能是糟糕的 google-fu。
我有这张桌子:
我正在尝试创建一个更新触发器,每当对or列执行更新时,该触发器就会更新last_updated_on = GETDATE()和last_updated_by = SYSTEM_USER列。step_numberstep_name
我开始创建它
ALTER TRIGGER tr_app_bread_crumbs_afterupdate
ON [dbo].[app_bread_crumbs]
AFTER UPDATE
AS
BEGIN
UPDATE [dbo].[app_bread_crumbs]
SET last_updated_by = SYSTEM_USER,
last_updated_on = GETDATE()
END
Run Code Online (Sandbox Code Playgroud)
但这将一次更新所有行。我正在尝试弄清楚如何指定仅更新last_updated_on和last_updated_by由正在更新的特定行的触发器。
例如,如果他们更新:
UPDATE [dbo].[app_bread_crumbs]
SET step_name = 'DAMAGE' WHERE step_number = 1
Run Code Online (Sandbox Code Playgroud)
触发器应该只更新第一行
trigger sql-server t-sql sql-server-2012 row-modification-time
trigger ×10
postgresql ×5
mysql ×3
plpgsql ×2
constraint ×1
datatypes ×1
date ×1
datetime ×1
performance ×1
select ×1
sql-server ×1
t-sql ×1