SQL存储过程如何实现软删除和数据恢复

酷杰小哥_6541

酷杰小哥_6541

2026-08-14

843人浏览

原创

软删除需配套deleted_at时间戳、deleted_by操作人、过滤索引及可审计恢复路径,而非仅is_deleted字段;查询应通过视图或存储过程默认隔离已删数据,恢复须经专用过程记录日志。

sql存储过程如何实现软删除和数据恢复

软删除不是加个 is_deleted 字段就完事,数据恢复也不是简单把字段改回来——关键在查询隔离、索引设计、恢复路径是否可审计,否则会漏查、慢查、甚至误恢复。

软删除字段必须带时间戳和操作人

只用 is_deleted BIT DEFAULT 0 是危险的:无法区分“谁删的”“什么时候删的”,后续恢复时容易覆盖真实业务逻辑(比如某条记录本该被新流程覆盖,结果被误还原)。

  • deleted_at DATETIME2 NULL(SQL Server)或 deleted_at TIMESTAMP NULL(MySQL),避免用 GETDATE() 直接赋默认值——它会在 INSERT 时就写入,而不是 DELETE 时
  • 必须配套 deleted_by VARCHAR(50) NULL,从应用层传入用户名/工号,不能靠触发器查 SYSTEM_USER,后者在连接池场景下不可靠
  • 建复合索引:CREATE INDEX IX_table_deleted_at ON table_name(deleted_at) WHERE deleted_at IS NOT NULL(SQL Server 过滤索引),否则全表扫描 WHERE deleted_at IS NULL 会越来越慢

SELECT 查询必须默认过滤已删除数据

应用代码里写 WHERE deleted_at IS NULL 容易漏,且分散难维护。更稳的方式是用视图或带条件的存储过程封装读取逻辑。

电子产品维修服务公司网站模板
电子产品维修服务公司网站模板

电子产品维修服务公司网站模板是一款提供手机、电脑、平板等维修服务的公司宣传网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。

下载
  • 不要依赖 ORM 的全局软删除钩子(如 Laravel 的 SoftDeletes trait),它可能被手动绕过或在 raw query 中失效
  • 推荐创建只读视图:CREATE VIEW v_orders AS SELECT * FROM orders WHERE deleted_at IS NULL,让业务查询只面向视图,物理表只供管理脚本访问
  • 如果必须用存储过程查,参数加 @include_deleted BIT = 0,默认不返回已删数据,需要时才显式传 1,避免误查

恢复数据不能只 UPDATE deleted_at

单纯执行 UPDATE orders SET deleted_at = NULL WHERE id = 123 会丢失删除上下文,且无法回溯“为什么恢复”。生产环境必须走可审计的恢复路径。

  • 恢复动作必须走专用存储过程,例如 usp_restore_order @order_id INT, @restored_by VARCHAR(50),内部做三件事:检查该记录是否真被软删(deleted_at IS NOT NULL)、INSERT 一条恢复日志到 restore_log 表、再 UPDATE 原表
  • restore_log 表至少含:idtable_namerecord_idrestored_byrestore_timeoriginal_deleted_at(方便比对时间差)
  • 禁止直接在应用层拼 SQL 恢复,尤其不能把 @order_id 直接拼进字符串——要用 sp_executesql + 参数化,哪怕只一个参数

大表软删除要防锁表和索引膨胀

对千万级订单表执行批量软删除(比如 UPDATE orders SET deleted_at = GETDATE() WHERE status = 'cancelled'),可能阻塞写入、撑爆事务日志、拖慢索引维护。

  • 分批执行:用 TOP (10000) + WHILE @@ROWCOUNT > 0 循环,每次提交事务,避免单次长事务
  • 避免在 deleted_at 上建非过滤索引——它会包含所有行,导致索引体积翻倍;只保留上面说的过滤索引(WHERE deleted_at IS NOT NULL
  • 定期归档真正废弃的数据:DELETE FROM orders WHERE deleted_at ,但必须先确认无下游依赖(如报表、对账系统还在查半年前的软删记录)

最常被忽略的是恢复后的数据一致性校验——比如订单恢复后,关联的支付流水、物流单是否仍有效?软删除和恢复从来不是单表操作,而是业务状态机的一环,不联动校验,就只是把数据“挪回原位”,不是真恢复。

相关文章

数据恢复工具app
数据恢复工具app

手机里的数据丢失了怎么办?聊天记录不小心删掉了怎么办?不用担心,这里为大家提供了数据恢复工具app下载,安全正规,有需要的小伙伴保存下载,就轻松恢复数据啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3743

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

791

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

969

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5521

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2503

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5500

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7161

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

970

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

852

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.1万人学习