标签: trigger

是否可以在触发器中获取执行调用堆栈?

我有 10 个存储过程,每个存储过程都将 INSERT 插入到一个 tableX 中。

是否可以在 tableX 的触发器主体中获取导致 tableX 修改的对象(存储的 proc1 或 sp2 或....)?

谢谢你。

trigger sql-server-2008

18
推荐指数
2
解决办法
1万
查看次数

限制对某些列的更新。只允许存储过程更新那些列

我有敏感的价格列,我只想通过存储过程进行更新。如果不使用旨在更新它的存储过程,我希望所有代码或手动尝试更改这些价格列中的值都失败。

我正在考虑使用触发器和令牌表来实现这一点。我正在考虑的想法是有一个令牌表。存储过程必须首先在令牌表中插入值。然后更新价格列。更新触发器将检查更新行的令牌表中是否存在该令牌。如果找到,它将继续。如果未找到令牌,则会抛出异常并使更新事务失败。

有没有好的/更好的方法来实现这个限制?

trigger sql-server stored-procedures t-sql sql-server-2012

18
推荐指数
2
解决办法
3万
查看次数

启用触发器时缓慢删除记录

认为这已通过以下链接解决 - 解决方法有效 - 但补丁没有。与 Microsoft 支持一起解决。

http://support.microsoft.com/kb/2606883

好的,所以我有一个问题,我想把它扔给 StackOverflow,看看是否有人有想法。

请注意,这是 SQL Server 2008 R2

问题:启用触发器时,从包含 15000 条记录的表中删除 3000 条记录需要 3-4 分钟,禁用触发器时只需 3-5 秒。

表设置

我们将称为 Main 和 Secondary 的两个表。Secondary 包含我要删除的项目记录,因此当我执行删除操作时,我会加入到 Secondary 表中。在删除语句之前运行一个进程,以使用要删除的记录填充辅助表。

删除声明:

DELETE FROM MAIN 
WHERE ID IN (
   SELECT Secondary.ValueInt1 
   FROM Secondary 
   WHERE SECONDARY.GUID = '9FFD2C8DD3864EA7B78DA22B2ED572D7'
);
Run Code Online (Sandbox Code Playgroud)

这个表有很多列和大约 14 个不同的 NC 索引。在我确定触发器是问题之前,我尝试了很多不同的事情。

  • 开启页面锁定(我们默认已关闭)
  • 手动收集统计数据
  • 禁用自动收集统计信息
  • 已验证的索引运行状况和碎片
  • 从表中删除聚集索引
  • 检查执行计划(没有任何显示为缺少索引,实际删除的成本为 70%,记录的连接/合并成本为 28%

触发器

该表有 3 个触发器(插入、更新和删除操作各一个)。我修改了删除触发器的代码以使其返回,然后选择一个以查看它被触发了多少次。它在整个操作过程中只触发一次(如预期的那样)。

ALTER TRIGGER [dbo].[TR_MAIN_RD] ON [dbo].[MAIN]
            AFTER DELETE
            AS  
                SELECT 1
                RETURN
Run Code Online (Sandbox Code Playgroud)

回顾

  • 使用 …

trigger performance sql-server delete sql-server-2008-r2

17
推荐指数
2
解决办法
4498
查看次数

从触发器调用存储过程

我使用以下语法在 mysql 中创建了一个存储过程。

DROP PROCEDURE IF EXISTS `sp-set_comment_count`;

DELIMITER $$

CREATE PROCEDURE `sp_set-comment_count` (IN _id INT)
BEGIN
   -- AC   - AllCount
   DECLARE AC INT DEFAULT 0;

   SELECT COUNT(*) AS ac
     INTO AC
     FROM usergroups AS ug
LEFT JOIN usergroup_comments AS ugm ON ugm.`gid` = ug.`id`
LEFT JOIN mediagallery AS dm ON ugm.mid = dm.`id`
    WHERE dm.`status` NOT IN (200, 201, 202, 203, 204, 205)
      AND ug.`id` = _id;

   UPDATE usergroups
      SET allCount = AC,
    WHERE usergroups.`id` = _id;

END $$ …
Run Code Online (Sandbox Code Playgroud)

mysql trigger stored-procedures

17
推荐指数
3
解决办法
10万
查看次数

如何检测对数据库的任何更改(DDL 和 DML)

我客户的 SQL 服务器上有很多数据库。这些数据库正在开发中,因此开发人员可以进行设计、重构、数据修改等。有一些数据库很少更改。我的客户必须确保所有这些都安全(备份)并花一些时间管理环境。(公司没有DB管理员职位。)经过长时间的讨论,客户决定使用每日完整备份策略,因为恢复容易。

所以这里是情况的总结:

  • 数据库的数量每天都在变化。
  • 应备份已更改的数据库(意味着数据和/或结构已更改)。
  • 未更改的数据库不得备份。
  • 解决方案不应影响数据库结构(不受限制的要求)
  • 这个“备份引擎”应自动工作。

主要问题:如何检测数据库已更改。问题的第一部分(DDL 更改)可以通过使用DDL 触发器来解决。但是数据更改(DML 更改)是一个问题。不可能将 DML 触发器应用于所有数据库的所有表以跟踪更改(性能、扩展对象的管理......)。备份引擎必须跟踪所有更改以将每个数据库标记为准备备份。

  • Change Data Capture是一个解决方案,但它似乎太重了(它还需要 SQL Server 企业版)。

  • 另一种方法是跟踪数据库文件更改(大小或上次更改时间),但它无法正常工作:当数据库超过所有保留的可用空间时,它可以更改其大小,而sp_spaceused不是解决方案。

  • 跟踪是一种解决方案,但它会导致性能问题并需要额外的管理。

是否有任何解决方案可以在不影响其他数据库管理对象(如统计信息..)的情况下计算实际数据库使用大小?当然,对不改变表大小的表数据的更改不会触发(我认为),但总比没有好。我真的在寻找 SQL Server 2008 的直接或间接解决方案。

感谢您的任何评论、解决方案和想法。

添加:

这是解决方案(感谢玛丽安):

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 sys.objects so
         ON so.object_id = p.object_id  
    WHERE 
    (
        (Operation …
Run Code Online (Sandbox Code Playgroud)

trigger sql-server-2008 backup

15
推荐指数
1
解决办法
5万
查看次数

Postgres 中的“转换表”是什么?

描述Postgres 10 新功能的页面提到了“触发器的转换表”。

触发器的转换表

此功能AFTER STATEMENT通过适当地向查询公开旧行和新行,使触发器既实用又高效。在此功能之前,AFTER STATEMENT触发器无法直接访问这些,并且变通方法是拜占庭式的并且性能很差。现在可以将许多触发器逻辑编写为AFTER STATEMENT,从而避免需要在 FOR EACH ROW 触发器所需的每一行进行昂贵的上下文切换。

什么是过渡表?

postgresql trigger table postgresql-10

15
推荐指数
2
解决办法
3774
查看次数

UPDATE 后触发 UPDATE?

我想制作一个触发器来记录任何更新的时间:

CREATE TRIGGER col_update
AFTER UPDATE ON col
FOR EACH ROW BEGIN
UPDATE col SET updated=NOW() WHERE id=NEW.id; // or OLD.id
END
Run Code Online (Sandbox Code Playgroud)

问题是当这个触发器尝试更新updated列时,它也是另一个更新事件,它运行触发器。这将创建一个无限循环,这是行不通的。

如何将更新时间存储在相应的列中?

我希望使用触发器,因为表中有很多列。如果我尝试手动设置更新时间,则需要修改许多查询。

mysql trigger update row-modification-time

14
推荐指数
1
解决办法
4万
查看次数

如何使用 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';
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

因此,203和的5值,以及1列的值,9因为它设置在第二个字节的第一位。如果我将语句更改为OR它会检查列3和/5或列9是否更新?

如何OR在一个字节的上下文中应用逻辑?

trigger sql-server t-sql

14
推荐指数
1
解决办法
3万
查看次数

PostgreSQL 中的更新后和更新前有什么区别

PostgreSQL 中的更新后和更新前有什么区别?我无法理解 和 之间的区别after updatebefore update因为看起来该函数总是在更新之前执行。

所以我做了下面的例子:

我做了一个函数,当状态为typing但延迟 10 秒时更新表。

CREATE OR REPLACE FUNCTION fai_prueba()
  RETURNS trigger AS
$BODY$
begin
    if new.status = 'Typing' then
        update image set status = 'ToTyping', path = 'Real path' from pg_sleep(5) where id = old.id;
    end if;
    return null;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION fai_prueba()
  OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)

然后我有以下触发器

create trigger tai 
after update on image 
for each row execute procedure fai_prueba();
Run Code Online (Sandbox Code Playgroud)

但是当我运行 UPDATE …

postgresql trigger functions

14
推荐指数
1
解决办法
8795
查看次数

MySQL存储例程中的动态SQL

根据存储例程和触发器限制,不能使用动态sql(5.0.13及以后版本的存储过程限制解除)。为什么会有这个限制?为什么将它提升为过程,而不是函数或触发器?

mysql trigger stored-procedures

13
推荐指数
2
解决办法
6544
查看次数