会,sql server 存储过程中本地临时表(#temp)在会话结束时自动清理,包括异常退出、断连或提前return,但未显式drop仍可能因残留索引、游标等引发资源卡顿。

SQL Server 存储过程中临时表会自动清理吗
会,但仅限 #temp 本地临时表——SQL Server 在会话结束时强制销毁,包括存储过程异常退出、客户端断连、甚至 RETURN 提前退出。但这不等于“安全”,因为:临时表残留本身不导致连接泄露,但若过程内建了索引、触发器或未关闭游标,这些资源可能卡住内存或锁。
MySQL 存储过程里 CLOSE cursor_name 必须配对出现
MySQL 的 sp_head::main_mem_root 内存不会随过程退出自动释放,尤其游标未 CLOSE 时,每次调用都在堆上累积。常见错误是只在正常路径写 CLOSE,却漏掉异常分支:
- 每个
DECLARE CURSOR后必须紧跟CLOSE,且放在END前 - 必须加
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION,并在其中显式CLOSE+LEAVE - 游标声明和
CLOSE必须在同一作用域块(BEGIN...END),跨块无效
PostgreSQL 临时表不加 ON COMMIT DROP 就会堆积
PostgreSQL 没有 # 语法糖,CREATE TEMP TABLE 默认存活到会话结束。如果应用用长连接反复调用同一存储过程,第二次执行就会报 relation "t1" already exists。解决方式非常明确:
- 必须写
CREATE TEMP TABLE t1 (...) ON COMMIT DROP - 不能省略
ON COMMIT DROP,只写CREATE TEMP TABLE是危险的 - 避免在临时表上执行
TRUNCATE—— 它不生效,生命周期由ON COMMIT控制
所有数据库都容易忽略的 NULL 传播问题
临时表字段含 NULL,后续 JOIN 或 WHERE 条件一旦没做 IS NULL 判断,结果集直接变空,看起来像“资源没释放”,其实是逻辑中断。更隐蔽的是:MySQL 的 SELECT INTO @var 遇到空结果会把变量设为 NULL,之后参与计算全变 NULL,最后写入临时表时字段全空——表面看表建了、数据也插了,实际是空壳。
真正难排查的不是连接或内存泄漏,而是这种“资源看似释放了,但中间结果已失效”的静默失败。











