标签: trigger

MySQL 中触发器与存储过程的性能

DBA.StackExchange 上的一篇文章(保持记录修订号的触发器的最佳实践是什么?)引发了一个关于 MySQL 性能的有趣问题(至少对我来说很有趣)。

上下文是我们要为更新的每一行在表中插入一条记录。在更新行之前,我们希望存储先前的值,然后增加其中一列(“版本”列)。

如果我们在触发器中执行此操作,效果会很好。对于 MySQL,触发器是逐行的,因此这将是一个简单的解决方案。选择表中当前的数据,将其插入到日志表中,并在新数据中更新“版本”列。

但是,可以将此逻辑移至存储过程。如果你这样做,你正在执行插入,然后增加表中的“版本”列。整个事情将基于设置。

那么,在执行此插入时,使用基于集合的存储过程方法或基于触发器的方法会更高效吗?

这个问题是针对 MySQL 的(因为它有逐行触发器),尽管它可以应用于其他逐行触发器 DBMS。

mysql trigger performance stored-procedures

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

为什么我没有在触发器中收到变异表错误?

众所周知(或至少是)您不能在触发器内的变异表上使用 DML 语句。Oracle 文档的摘录:

变异表是由 UPDATE、DELETE 或 INSERT 语句修改的表,或者可能受 DELETE CASCADE 约束影响更新的表。

发出触发语句的会话不能查询或修改变异表。此限制可防止触发器看到一组不一致的数据。

但是,当我执行insert into empusing 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;
Run Code Online (Sandbox Code Playgroud)

插入成功完成下一个id值并更新所有emp记录。我使用的是 Oracle 数据库 11g 企业版 11.2.0.1.0 版。我已阅读有关复合触发器的信息,但示例并未使用它们。

trigger oracle oracle-11g

11
推荐指数
1
解决办法
6350
查看次数

在 PostgreSQL 8.4 中执行触发器函数需要什么权限?

在 PostgreSQL 8.4 中执行触发器函数需要什么权限?

似乎为角色设置的权限与执行触发器功能无关。我想我有一天看到执行触发器函数所需的特权是 EXECUTE 特权,但对于表的所有者,而不是执行触发调用触发器函数的触发器的操作的实际角色。

我找不到解释这一点的文档部分,有什么帮助吗?

postgresql trigger stored-procedures permissions postgresql-8.4

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

使用触发器进行同步

我有一个类似于之前讨论的要求:

我有两张桌子,[Account].[Balance]并且[Transaction].[Amount]

CREATE TABLE Account (
      AccountID    INT
    , Balance      MONEY
);

CREATE TABLE Transaction (
      TransactionID INT
     , AccountID    INT
    , Amount      MONEY
);
Run Code Online (Sandbox Code Playgroud)

当对[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 from [Inserted])
    UPDATE [dbo].[Account]
    SET
    [Account].[Balance] = [Account].[Balance] + 
        (
            Select ISNULL(Sum([Inserted].[Amount]),0)
            From [Inserted] 
            Where [Account].[AccountID] = [Inserted].[AccountID]
        )
        - …
Run Code Online (Sandbox Code Playgroud)

trigger sql-server transaction acid data-synchronization

11
推荐指数
1
解决办法
5159
查看次数

在时态数据库设计中确保唯一条目的正确方法是什么?

我在设计时态数据库时遇到问题。我需要知道如何确保在商店的任何给定时间范围内我只有一个活动记录。我已经阅读了这个答案,但恐怕我无法理解触发器的工作原理。特别是,我如何将触发器工作到我现有的触发器中,以防止更新记录,而是插入新记录。我真正的问题是,当完成日期为空时,我不知道如何防止 Store 有多个生效日期。(即防止商店的 2 个活动记录)。

这就是我所拥有的,但它允许我为具有不同生效日期的商店插入新记录。

表定义:

/****** Object:  Table [PCR].[Z_STORE_TEAM]    Script Date: 05/09/2014 13:05:57 ******/
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[Z_STORE_TEAM]') AND type in (N'U'))
DROP TABLE [Z_STORE_TEAM]
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[Z_STORE_TEAM]') AND type in (N'U'))
BEGIN
CREATE TABLE [Z_STORE_TEAM](
    [STORENUM] [int] NOT NULL,
    [TEAM] [varchar](10) NULL,
    [EFFECTIVE] [date] NOT NULL,
    [FINISHED] [date] NULL,
PRIMARY KEY CLUSTERED 
(
    [STORENUM] ASC,
    [EFFECTIVE] ASC
)WITH (PAD_INDEX  = …
Run Code Online (Sandbox Code Playgroud)

trigger database-design sql-server t-sql

11
推荐指数
1
解决办法
1400
查看次数

如何防止 PostgreSQL 触发器被另一个触发器触发?

我在一张桌子上有 2 个触发器;一种适用于插入:

CREATE TRIGGER "get_user_name"
AFTER INSERT ON "field_data"
FOR EACH ROW EXECUTE PROCEDURE "add_info"();
Run Code Online (Sandbox Code Playgroud)

这会更新表中的一些值。
还有一个用于更新(填充历史表):

CREATE TRIGGER "set_history"
BEFORE UPDATE ON "field_data"
FOR EACH ROW EXECUTE PROCEDURE "gener_history"();
Run Code Online (Sandbox Code Playgroud)

问题是,当我在表中插入新行时,该过程"add_info"()会进行更新并因此触发第二个触发器,该触发器以错误结束:

ERROR:  record "new" has no field "field1"
Run Code Online (Sandbox Code Playgroud)

我怎样才能避免这种情况?

postgresql trigger plpgsql postgresql-9.3

11
推荐指数
2
解决办法
7709
查看次数

当sql server触发器失败时,我们可以提交事务吗?

当表上的插入触发器失败时,我试图避免数据丢失。我正在使用以下场景尝试此操作,但我的代码失败了。

当在客户表上发生插入时,我想将相同的数据插入到存档表中。当触发器失败时,我不想回滚整个事务,这会导致客户表上的数据丢失。

即使触发器失败,我也希望将数据插入到Customers表中,并且存储过程应该像往常一样返回Customer_ID

ALTER TRIGGER [dbo].[Customer_Insert_Trigger_Test] 
   ON  [dbo].[Customers]
   AFTER INSERT
AS 
BEGIN

BEGIN TRY
    begin transaction;
    set nocount  on;
    SAVE TRANSACTION InsertSaveHere;
    --Simulating error situation
    RAISERROR (N'This is message %s %d.', -- Message text.
       11, -- Severity,
       1, -- State,
       N'number', -- First argument.
       5); -- Second argument.

   Insert into Archive select * from Inserted;
    commit transaction;

  END TRY

  BEGIN CATCH
    ROLLBACK TRANSACTION InsertSaveHere;
  END CATCH
END
Run Code Online (Sandbox Code Playgroud)

我的问题主要是关于如何避免在客户表上的实际插入以在触发器失败时回滚。如何更改我的代码?

trigger sql-server transaction

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

使用跨数据库证书时触发器中的权限

我使用跨数据库证书(如 Erland Sommarskog 所述)来控制对我环境中某个数据库的访问(SQL Server 2008 R2)。

我在数据库 A 中存储了更新数据库 B 中表的存储过程。直到现在,这一直适用于 db A 中的各种存储过程和 db B 中的表。我正在尝试更新 db B 中的表,但该表上有一个触发器。此触发器在 db B 的另一个表中插入其他数据。我收到错误消息:

消息 916,级别 14,状态 1,过程 table_trigger,第 11 行 服务器主体“sql\login”在当前安全上下文下无法访问数据库“B”。

我尝试为与证书绑定的数据库 B 用户授予插入权限以插入其他表,但它没有解决错误。除了更改触发器以使其使用之外,我还有其他选择WITH EXECUTE AS OWNER吗?

这是复制问题的 DDL:

CREATE LOGIN [GuggTest] WITH PASSWORD=N'abcd', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF

CREATE DATABASE A;
CREATE DATABASE B;

USE A;

CREATE TABLE dbo.SPtoUpdate
    (
      ID INT
    , ILoveFishing VARCHAR(255)
    );
INSERT INTO dbo.SPtoUpdate
        ( ID , ILoveFishing )
VALUES  ( …
Run Code Online (Sandbox Code Playgroud)

trigger sql-server permissions signature certificate

11
推荐指数
1
解决办法
2131
查看次数

如何检查触发器是否在 INSERT、UPDATE 或 DELETE 语句上触发?

如何确定触发器是针对 INSERT、UPDATE 还是 DELETE 语句?

我已签入sys.triggers,但看不到与触发器触发的操作相关的任何内容。

trigger sql-server

11
推荐指数
1
解决办法
922
查看次数

使用 INSTEAD OF 触发器合并到视图中

我有一个带有触发器的视图instead of,我尝试将其与 EF Core 一起使用,EF Core 尝试以merge语句的形式将批量插入一起。这是我的表格和视图:

create table tbl (id uniqueidentifier not null primary key, data nvarchar(max) null)
go
create view vwTbl as select * from tbl
go
create trigger vwTblInsert on vwTbl instead of insert as
    insert into tbl (id, data)
    select id, data
    from inserted
go
Run Code Online (Sandbox Code Playgroud)

以下是 EF 生成的近似 SQL:

declare @inserted1 table ([id] uniqueidentifier);
merge vwTbl using (
    values (newid(), 'xxx') 
) as i (id, data) on 1=0
when not matched then …
Run Code Online (Sandbox Code Playgroud)

trigger sql-server entity-framework merge sql-server-2019

11
推荐指数
2
解决办法
1807
查看次数