You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在不影响客户端的前提下快速删除含大量触发器的表行?

嘿,这个需求非常典型——既要快速删除数据,又不想触发表上的触发器,同时还不能影响其他客户端的正常使用,对吧?你想要的那种单语句带触发器禁用的写法,不同数据库的实现方式略有不同,我给你分主流数据库整理了方案:

不同数据库的具体实现

MySQL/MariaDB

MySQL没有直接在DELETE语句里嵌入禁用触发器的语法,但可以用会话级别的临时设置来实现,这个设置只会对你当前的数据库连接生效,完全不会影响其他客户端:

-- 先保存当前的SQL模式,方便后续恢复
SET @original_sql_mode = @@session.sql_mode;
-- 开启当前会话的触发器禁用模式
SET @@session.sql_mode = CONCAT(@@session.sql_mode, ',NO_TRIGGERS');
-- 执行你的删除操作
DELETE FROM mySchem.myTable WHERE id = 99;
-- 恢复原来的SQL模式,避免影响后续操作
SET @@session.sql_mode = @original_sql_mode;

注意:这个NO_TRIGGERS模式是MySQL 8.0.19及以上版本才支持的,如果是旧版本,建议用事务包裹临时重命名触发器的操作,但这种方法风险略高,优先升级版本或者用会话级设置。

PostgreSQL

PostgreSQL完美支持你想要的单语句写法,直接在DELETE后面加DISABLE TRIGGER子句即可,这个操作仅对当前DELETE语句生效:

-- 禁用当前删除操作的所有触发器
DELETE FROM mySchem.myTable WHERE id = 99 DISABLE TRIGGER ALL;

如果你只想禁用特定的某个触发器(而不是全部),把ALL换成触发器名称就行:

DELETE FROM mySchem.myTable WHERE id = 99 DISABLE TRIGGER my_target_trigger;

SQL Server

SQL Server没有单语句禁用触发器的语法,但可以用事务包裹临时禁用/启用触发器的操作,保证原子性,不会影响其他客户端:

BEGIN TRANSACTION;
-- 临时禁用表上的所有触发器
ALTER TABLE mySchem.myTable DISABLE TRIGGER ALL;
-- 执行删除
DELETE FROM mySchem.myTable WHERE id = 99;
-- 立刻恢复触发器
ALTER TABLE mySchem.myTable ENABLE TRIGGER ALL;
COMMIT TRANSACTION;

这个操作全程在事务里完成,触发器只会被禁用极短时间,其他客户端几乎感知不到。

Oracle

Oracle可以通过会话级设置或者表级临时禁用触发器来实现,推荐用事务包裹表级操作,更安全:

BEGIN TRANSACTION;
-- 禁用目标表的所有触发器
ALTER TABLE mySchem.myTable DISABLE ALL TRIGGERS;
-- 执行删除
DELETE FROM mySchem.myTable WHERE id = 99;
-- 恢复触发器
ALTER TABLE mySchem.myTable ENABLE ALL TRIGGERS;
COMMIT TRANSACTION;

如果你只想对当前会话禁用触发器,也可以用:

ALTER SESSION SET DISABLE_TRIGGERS = TRUE;
DELETE FROM mySchem.myTable WHERE id = 99;
ALTER SESSION SET DISABLE_TRIGGERS = FALSE;

内容的提问来源于stack exchange,提问作者Jaytt Correa

火山引擎 最新活动