Questions tagged «trigger»

响应数据库事件自动执行过程代码。

5
如何检测对数据库的任何更改(DDL和DML)
我的客户端的SQL服务器上有很多数据库。这些数据库正在开发中,因此开发人员可以设计,重构,进行数据修改等。有些数据库很少更改。我的客户必须确保所有人(备份)的安全,并花一些时间来管理环境。(该公司没有数据库管理员的职位。)经过长时间的讨论,由于易于还原,客户决定使用每日完全备份策略。 因此,这是情况的摘要: 数据库的数量每天都会变化。 更改的数据库(意味着数据和/或结构已更改)应备份。 未更改的数据库不得备份。 解决方案不得影响数据库结构(这不是限制性要求) 该“备份引擎”将自动工作。 主要问题:如何检测数据库已更改。问题的第一部分(DDL更改)可以通过使用DDL触发器来解决。但是数据更改(DML更改)是一个问题。无法将DML触发器应用于所有数据库的所有表以跟踪更改(性能,扩展对象的管理...)。备份引擎必须跟踪所有更改,以将每个数据库标记为准备备份。 更改数据捕获是一种解决方案,但似乎过于繁琐(它也需要SQL Server Enterprise Edition)。 另一种方法是跟踪数据库文件的更改(大小或上次更改时间),但无法正常工作:当数据库超出所有保留的可用空间并且sp_spaceused不是解决方案时,数据库可以更改其大小。 跟踪是一种解决方案,但它会导致性能问题并需要其他管理。 是否有解决方案可以计算实际的数据库使用量,而又不影响其他数据库管理对象(如统计数据……)?可以肯定的是,对表数据的更改不会改变表的大小不会触发(我认为),但这总比没有好。确实,我在寻找SQL Server 2008的直接或间接解决方案。 感谢您的任何评论,解决方案和想法。 添加: 这是解决方案(感谢Marian): Select NextLSN = MAX(fn.[Current LSN]) ,Databasename = DB_NAME() from fn_dblog(NULL, NULL) fn LEFT JOIN sys.allocation_units au ON fn.AllocUnitId = au.allocation_unit_id LEFT JOIN sys.partitions p ON p.partition_id = au.container_id LEFT JOIN …


1
如何使用COLUMNS_UPDATED检查某些列是否已更新?
我有42列的表格和一个触发器,当其中38列更新时,触发器应该做一些事情。因此,如果其余4列已更改,则需要跳过逻辑。 我可以使用UPDATE()函数并创建一个大IF条件,但更喜欢做一些简短的事情。使用COLUMNS_UPDATED,我可以检查某些列是否全部已更新? 例如,检查第3、5和9列是否已更新: IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1) & 20 = 20) AND (SUBSTRING(COLUMNS_UPDATED(),2,1) & 1 = 1) ) PRINT 'Columns 3, 5 and 9 updated'; 因此,请20为column 3和的5值以及1为column的值,9因为它是在第二个字节的第一位中设置的。如果我将语句更改为OR它,则将检查列3和5或列9是否已更新? 如何OR在一个字节的上下文中应用逻辑?

2
在Postgres中什么是“转换表”?
描述Postgres 10中新功能的页面提到“触发器的转换表”。 触发器的转换表 AFTER STATEMENT通过适当地向查询公开新旧行,此功能使触发器既有用又高效。在使用此功能之前,AFTER STATEMENT触发器无法直接访问这些触发器,并且变通办法是拜占庭式的并且性能较差。现在,可以将许多触发逻辑编写为AFTER STATEMENT,从而避免了对FOR EACH ROW触发器所需的每一行进行昂贵的上下文切换的需要。 什么是过渡表?

4
将来自不同表的数据聚合到一个表中是不明智的做法吗?
背景 我为大量的健康记录数据库写了很多大型报告(写SP,函数,作业等)。原始模式和使用该模式的软件均来自其他供应商,因此我在结构上不能做太多更改。有许多需要跟踪的记录,例如实验室,程序,疫苗等,它们分散在数十张表中,其中许多表肿且索引不正确(我已经能够解决此问题)。 问题 问题是,由于我们对数据库的控制很少,并且可以从任何给定的更新或补丁进行更改,因此使得编写和维护这些报告变得困难而乏味-特别是在存在大量重叠的情况下。它所需要的只是一个补丁,我被困在重写大量报告中的大部分。此外,随着联接,嵌套选择和应用堆积,查询很快变得混乱而缓慢。 我的“解决方案” 我的计划是将所有这些记录写入一个“全部捕获”表,并在原始表上写入触发器以维护该聚合表中的记录。当然,我需要确保触发器在更新后完好无损,但是从可维护性的角度来看,并且仅引用数据,这样做会容易得多。 该表又细又长,仅存储所需的数据,如下所示: CREATE TABLE dbo.HCM_Event_Log ( id INT IDENTITY, type_id INT NULL, orig_id VARCHAR(36) NULL, patient_id UNIQUEIDENTIFIER NOT NULL, visit_id UNIQUEIDENTIFIER NULL, lookup_id VARCHAR(50) NULL, status VARCHAR(15) NULL, ordered_datetime DATETIME NULL, completed_datetime DATETIME NULL, CONSTRAINT PK_HCM_Event_Log PRIMARY KEY CLUSTERED (id) ) 然后,我将使用各种关系表来处理诸如type_id和项目分组之类的事情。 我开始对这个想法进行第二次猜测,因为其中一些表已写入很多,我要编写的SP和报告也将大量引用数据。因此,我担心此表将成为具有这么多I / O的记录锁定和性能噩梦。 …

2
突变表错误的原因和解决方案是什么?
我了解突变表错误是由设计缺陷或有问题的查询引起的。 最近将一个旧查询投入生产,该查询引发了变异表错误。我们的DBA解决了问题,但我们不知道如何解决。 究竟是什么导致表突变错误?我们的DBA如何解决该问题?
12 oracle  trigger  plsql 

3
如何更改触发器的触发顺序?
真的,我很少使用触发器。所以我第一次遇到一个问题。我有很多带有触发器的表(每个表2个或更多)。我想知道并更改每个表的触发触发器的顺序。是否可以获取此信息? 添加: 这是我发现的有关mssqltips的一篇不错的文章。

5
在触发器中将INSERTED和DELETED表联接在一起的糟糕表现
我在表上有一个UPDATE触发器,该触发器监视从一个特定值更改为任何其他值的特定列。发生这种情况时,它将通过单个UPDATE语句更新另一个表中的一些相关数据。 触发器要做的第一件事是检查是否有任何更新的行使该列的值与所讨论的值发生了变化。它只是将INSERTED与DELETED连接起来,并比较该列中的值。如果没有任何条件,它将尽早解决,因此UPDATE语句不会运行。 IF NOT EXISTS ( SELECT TOP 1 i.CUSTNMBR FROM INSERTED i INNER JOIN DELETED d ON i.CUSTNMBR = d.CUSTNMBR WHERE d.CUSTCLAS = 'Misc' AND i.CUSTCLAS != 'Misc' ) RETURN 在这种情况下,CUSTNMBR是基础表的主键。如果我对此表进行了大的更新(例如,超过5000行),则即使我没有触摸CUSTCLAS列,该语句也需要AGES。我可以在Profiler中看到它在此语句上停滞了几分钟。 执行计划很奇怪。它显示了具有3,714次执行和约1,850万个输出行的插入扫描。通过CUSTCLAS列上的过滤器运行。它将其(通过嵌套循环)连接到“删除的扫描”(也已在CUSTCLAS上过滤),该“删除的扫描”仅执行一次并且有5000条输出行。 我在这里做什么愚蠢的事情导致这个?请注意,触发器绝对必须正确处理多行更新。 编辑: 我也尝试过这样写(以防EXISTS做不愉快的事情),但它仍然一样糟糕。 DECLARE @CUSTNMBR varchar(31) SELECT TOP 1 @CUSTNMBR = i.CUSTNMBR FROM INSERTED i INNER JOIN …

2
如果操作是由带有UPDATE CASCADE的FK约束引起的,则FOR EACH STATEMENT触发器多久执行一次?
我了解FOR EACH STATEMENT在执行时,表t上定义的触发器将运行一次UPDATE t ...。 现在,当使用t定义时FOREIGN KEY ... REFERENCES a ... ON UPDATE CASCADE,我更新的N行a,这会导致触发器被调用一次或N次吗? 换句话说,由FK约束级联的表更改更像是单个UPDATE,还是更像一系列UPDATEs?

3
将有关已删除记录的信息传递到“删除”触发器上
在设置审计跟踪时,我没有问题可以跟踪谁在更新或在表中插入记录,但是,跟踪谁删除记录似乎更成问题。 我可以通过在“插入/更新”字段中包含“ UpdatedBy”字段来跟踪插入/更新。这使INSERT / UPDATE触发器可以通过来访问字段“ UpdatedBy” inserted.UpdatedBy。但是,使用Delete触发器不会插入/更新数据。有没有一种方法可以将信息传递到Delete触发器上,以便它可以知道谁删除了记录? 这是一个插入/更新触发器 ALTER TRIGGER [dbo].[trg_MyTable_InsertUpdate] ON [dbo].[MyTable] FOR INSERT, UPDATE AS INSERT INTO AuditTable (IdOfRecordedAffected, UserWhoMadeChanges) VALUES (inserted.ID, inserted.LastUpdatedBy) FROM inserted 使用SQL Server 2012

1
在PostgreSQL 8.4中执行触发功能需要哪些特权?
在PostgreSQL 8.4中执行触发功能需要哪些特权? 似乎为角色设置的特权与执行触发功能无关紧要。我想我已经看到有一天执行触发器功能所需的特权是EXECUTE特权,但对于表的所有者而言,而不是执行触发触发器的触发器的实际角色。 我找不到说明这一点的文档部分,有什么帮助吗?

1
为什么在触发器中没有出现变异表错误?
众所周知(或至少是这样),您不能在触发器内的变异表上使用DML语句。Oracle文档摘录: 变异表是由UPDATE,DELETE或INSERT语句修改的表,或者是可能由DELETE CASCADE约束的影响而更新的表。 发出触发语句的会话无法查询或修改变异表。此限制可防止触发器看到不一致的数据集。 但是,我无法理解为什么当我insert into emp使用SQL Developer或SQL * Plus 执行此演示触发器时不会出现“突变表”错误: CREATE OR REPLACE TRIGGER emp_bri BEFORE INSERT ON emp FOR EACH ROW BEGIN SELECT max(id) + 1 INTO :NEW.id FROM emp; UPDATE emp SET salary = 5000; END emp_bri; 插入成功完成并显示下一个id值,并更新所有emp记录。我正在使用Oracle Database 11g企业版11.2.0.1.0。我已经阅读了有关复合触发器的信息,但样本未使用它们。


2
通过PostgreSQL中的视图和触发器跟踪当前用户
我有一个PostgreSQL(9.4)数据库,该数据库根据当前用户限制对记录的访问,并跟踪用户所做的更改。这是通过视图和触发器实现的,并且在大多数情况下都可以正常工作,但是我在需要INSTEAD OF触发器的视图中遇到了问题。我试图减少问题的发生,但是我很抱歉这仍然很长。 情况 与数据库的所有连接都是通过Web前端通过单个帐户进行的dbweb。连接后,通过SET ROLE使用Web界面更改角色以使其与该人相对应,并且所有这些角色都属于组角色dbuser。(有关详细信息,请参见此答案)。假设用户为alice。 我的大多数表都放在一个架构中,在这里我将对其进行调用private并属于dbowner。这些表不能直接访问dbuser,但可以用作另一个角色dbview。例如: SET SESSION AUTHORIZATION dbowner; CREATE TABLE private.incident ( incident_id serial PRIMARY KEY, incident_name character varying NOT NULL, incident_owner character varying NOT NULL ); GRANT ALL ON TABLE private.incident TO dbview; 特定行对当前用户的可用性alice由其他视图确定。一个简化的示例(可以减少,但需要通过这种方式来支持更一般的情况)将是: -- Simplified case, but in principle could join multiple tables to determine allowed …

1
使用触发器进行同步
我的要求与之前的讨论类似: 编写一个简单的银行架构:如何使我的余额与他们的交易记录保持同步? 结合交易触发 我有两个表,[Account].[Balance]和[Transaction].[Amount]: CREATE TABLE Account ( AccountID INT , Balance MONEY ); CREATE TABLE Transaction ( TransactionID INT , AccountID INT , Amount MONEY ); 当对该[Transaction]表进行插入,更新或删除时,[Account].[Balance]应基于进行更新[Amount]。 目前,我有一个触发器可以完成此任务: ALTER TRIGGER [dbo].[TransactionChanged] ON [dbo].[Transaction] AFTER INSERT, UPDATE, DELETE AS BEGIN IF EXISTS (select 1 from [Deleted]) OR EXISTS (select 1 …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.