一尘不染

MySQL 存储例程中的动态 SQL

mysql

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


阅读 58

收藏
2022-10-13

共1个答案

一尘不染

光是听到这个问题,我就想到了两个方面:

方面#1:函数应该是确定性的

如果是这样,这意味着函数应该为给定的一组参数一致地呈现相同的返回数据,无论何时调用该函数。

现在,想象一个函数,由于基于函数中的静态 SQL 在一天中的不同时间收集数据而产生不同的答案。从某种意义上说,如果您每次都查询相同的表和列集,并且给定相同的参数集,那么这仍然可以被认为是确定性的。

如果您可以通过动态 SQL 更改函数的基础表会怎​​样?您违反了 DETERMINISTIC 函数的定义。

注意 MySQL 在 /etc/my.cnf 中添加了这个选项

log-bin-trust-function-creators
虽然这可能过于简单化了,但这允许函数将数据写入二进制日志,而无需严格执行 DETERMINISTIC 属性。

方面#2:触发器应该能够回滚

您能想象一个触发器具有与函数相同的所有行为,然后将动态 SQL 引入组合中吗?
您能想象在将MVCC应用到触发器所针对的基表之后尝试对动态 SQL应用MVCC(多版本并发控制)吗?
仅在 MVCC 中,您基本上就会拥有以二次方(甚至指数方式)增长的数据。至少可以说,使用可能是非确定性的触发器来管理 SQL 回滚的过程将非常复杂。

鉴于这两个方面,我敢肯定 MySQL 开发人员想到了这些事情,并通过施加限制迅速将它们排除在外。

那么,为什么要解除对程序的限制呢?简而言之,无需担心 DETERMINISTIC 属性或回滚。

2022-10-13