更新11.15.2022
我进行了广泛的测试,发现了这里的问题模式。再一次,奇怪的是,只有当您将函数作为参数传递给原始存储过程时,才会发生这种情况;传递硬编码的值或变量效果很好。
问题是当存储过程调用另一个存储过程时,该存储过程只检查@@read_only以查看是否可以写入数据库。我确认删除任何写入数据的代码都可以解决这个问题——所以最终它似乎会将一个STATIC值传递给SP,导致过程执行绕过任何写入(如预期(,因为IF@@read_only=FALSE THEN。。。写
它似乎以某种方式传递了一个函数,导致MySQL编译一个";树;调用和子调用,看看他们是否能写,而不是是否能写。
解决这一问题的唯一方法似乎是将参数作为变量而不是函数调用传递。我们可以做到这一点,但这需要大量的重构。
我只是想知道MySQL为什么要这样做——为什么传递一个函数会让系统向前看,看看它是否可以写,而不是它是否可以。
我们有一个运行良好的读取副本。我们可以毫无问题地执行对它的读取。
我们可以做到:
CALL get_table_data(1, 1, "SELECT * from PERSON where ID=1;", @out_result, @out_result_value);
它执行得很好。请注意,它带有READS SQL DATA标记。它没有写出任何内容。
我们也可以这样做:
SELECT get_value("OBJECT_BASE", "NAME");
这是只读的SELECT函数。
然而,如果我们尝试执行以下操作:
CALL get_table_data(1, get_value("OBJECT_BASE", "NAME"), "SELECT * from PERSON where ID=1;", @out_result, @out_result_value);
我们得到错误:
Error: ER_OPTION_PREVENTS_STATEMENT: The MySQL server is running with the --read-only option so it cannot execute this statement
我们对造成这种情况的原因感到困惑。SP和函数都是只读的,单独执行也很好,但当我们将函数结果嵌入SP的调用中时,系统就会阻塞。
有什么想法吗?
所以AWS无法解决这个问题。只有当函数作为参数传递给调用另一个存储过程(甚至不传递函数的值(的存储过程时,才会发生此问题,该存储过程在执行INSERT或UPDATE之前具有@@read_only检查。因此,出于某种原因,系统在传递函数时会对变量或硬编码值进行预扫描检查。
解决方法是将函数值作为变量传递。
我将向Oracle报告这个问题,因为它可能是某种错误,特别是考虑到函数是确定性的。