根据 对存储的例程和触发器的限制, ,无法使用动态SQL(在版本5.0.13及以后的存储过程中提起限制)。为什么要有这种限制?为什么要将其提起以进行程序,而不是功能或触发器?

有帮助吗?

解决方案

只是听到这个问题使我想到了两个方面:

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

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

现在,想象一个函数,该函数由于函数中的静态SQL在一天的不同时间收集数据而产生不同的答案。从某种意义上说,如果您每次(给定相同的参数集)查询相同的表格和列,仍然可以考虑确定性。

如果您可以通过动态SQL更改函数的基础表怎么办?您违反了确定性功能的定义。

请注意,MySQL在/etc/my.cnf中添加了此选项

log-bin-trust-function-creators

尽管这可能是一个过分的简化,但这允许允许函数将数据写入二进制日志中,而无需严格执行确定性属性。

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

  • 您能想象所有具有与函数相同行为的触发器,然后将动态SQL引入混合物中吗?
  • 你能想象要申请 MVCC(多元偶发控制) 在将MVCC应用于基础表之后,触发器的目的是反对动态SQL。

您本质上只有仅在MVCC中就可以(甚至是指数)增长的数据。至少可以说,使用可能是非确定性的触发器来管理SQL的回滚过程将是不敬虔的。

鉴于这两个方面,我敢肯定,MySQL开发人员对这些事情进行了思考,并通过施加限制来迅速消除它们。

那么,为什么要取消对程序的限制?简而言之,对确定性属性或回滚不关心。

其他提示

这是一个很好的问题,但我不知道答案。我想这将不得不获得内部团队,但我不知道他们会很重要。同时,我可以帮助您推断出一些答案。

对于初学者,我看到了:

触发器缓存未检测到基础对象的元数据发生变化。如果触发器使用表,并且自触发器加载到缓存中以来该表已更改,则触发器将使用过时的元数据进行操作。

这让我认为这与它有关。如果它甚至不监视元数据,它将不会重新编译SQL。这意味着这是引擎的关注点。

同样,当我阅读此块时,我认为同样的事情(引擎):

为了防止服务器线程之间的交互问题,当客户端发出语句时,服务器使用可用于执行语句的例程和触发器的快照。也就是说,服务器计算在执行语句期间可以使用的过程,功能和触发器的列表,加载它们,然后继续执行语句。这意味着,尽管语句执行,但不会看到其他线程执行的例程的更改。

因此,总而言之,我不完全确定他们为什么不允许它,但是我可以猜到。抱歉,我无法为您提供更多帮助,我愿意将其更多。最好的是希望一旦我们离开私人beta,就希望有一些活跃的mysql devs;)

在很大程度上,这是由于安全性。过程的例外是因为可以为执行用户的安全上下文分配过程中的动态SQL。这意味着即使引擎不知道 什么 将要执行,可以确保允许用户访问引用的对象。

除此之外,如果允许,您可以提出可能发生的事情的丑陋问题。

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top