SQL dinámico en rutinas almacenadas de MySQL

Respuestas:

8

Solo escuchar la pregunta me hace pensar en dos aspectos:

ASPECTO # 1: Se supone que las funciones son DETERMINISTAS

Si esto es así, esto implica que una función debe presentar los mismos datos de retorno consistentemente para un conjunto dado de parámetros, NO IMPORTA CUANDO LLAME A LA FUNCIÓN.

Ahora, imagine una función que produce una respuesta diferente debido a la recopilación de datos en diferentes momentos del día en función de SQL estático en la función. En cierto sentido, eso todavía puede considerarse DETERMINISTA si consulta el mismo conjunto de tablas y columnas cada vez, dado el mismo conjunto de parámetros.

¿Qué pasaría si pudiera cambiar las tablas subyacentes de una función a través de Dynamic SQL? Está violando la definición de una función DETERMINISTICA.

Tenga en cuenta que MySQL agregó esta opción en /etc/my.cnf

log-bin-trust-function-creators

Aunque esto puede ser una simplificación excesiva, esto permite que las funciones puedan escribir datos en registros binarios sin aplicar estrictamente la propiedad DETERMINISTIC.

ASPECTO # 2: Los disparadores deberían poder revertirse

  • ¿Te imaginas un disparador con los mismos comportamientos que una función y luego introducir SQL dinámico en la mezcla?
  • ¿Te imaginas tratar de aplicar MVCC (Control de concurrencia multiversional) contra SQL dinámico después de aplicar MVCC a la tabla base para la que estaba destinado el disparador?

Esencialmente, tendría datos que crecen cuadráticamente (incluso exponencialmente) solo en MVCC. El proceso de gestionar la reversión de SQL con desencadenadores que pueden ser no DETERMINISTOSOS sería, por decir lo menos, complejo de impío.

A la luz de estos dos aspectos, estoy seguro de que los desarrolladores de MySQL pensaron en estas cosas y rápidamente las descartaron imponiendo restricciones.

Entonces, ¿por qué levantar la restricción de procedimientos? En pocas palabras, no hay preocupación por las propiedades DETERMINISTAS o la reversión.

RolandoMySQLDBA
fuente
3
No puede ser tan "complejo impío" si otros DBMS pueden soportar MVCC y SQL dinámico en los disparadores.
a_horse_with_no_name
1
En realidad, @a_horse_with_no_name, tienes razón. Para Oracle y PostgreSQL, el complejo impío ha sido codificado. +1 por tu comentario MySQL tiene la desventaja de tratar con múltiples motores de almacenamiento, por lo que la reversión y el determinismo pueden requerir la superposición de las operaciones del motor de almacenamiento. Eso da un poco de miedo. Tal vez alguien tenga las agallas para empujar "complejo impío" en InnoDB en su totalidad. Aún más deseable sería crear una implementación de activación específica del motor de almacenamiento de tal manera que no permita mezclar motores de almacenamiento dentro de la misma consulta.
RolandoMySQLDBA
5

Esta es una gran pregunta, pero no sé la respuesta. Me imagino que esto tendrá que ir al equipo interno, pero no sé si serán grandes en este sitio. Mientras tanto, puedo ayudarte a deducir algunas respuestas.

Para empezar veo esto:

El caché de disparo no detecta cuándo los metadatos de los objetos subyacentes han cambiado. Si un activador usa una tabla y la tabla ha cambiado desde que el activador se cargó en la memoria caché, el activador funciona utilizando los metadatos obsoletos.

Lo que me hace pensar que eso tiene algo que ver con eso. No va a recompilar SQL si ni siquiera está monitoreando los metadatos. Lo que significa que es una preocupación del motor.

Del mismo modo, cuando leo este bloque, pienso lo mismo (motor):

Para evitar problemas de interacción entre los subprocesos del servidor, cuando un cliente emite una declaración, el servidor utiliza una instantánea de rutinas y disparadores disponibles para la ejecución de la declaración. Es decir, el servidor calcula una lista de procedimientos, funciones y desencadenantes que pueden usarse durante la ejecución de la declaración, los carga y luego procede a ejecutar la declaración. Esto significa que mientras se ejecuta la instrucción, no verá cambios en las rutinas realizadas por otros hilos.

Así que, en general, no estoy completamente seguro de por qué no lo permiten, pero puedo adivinar. Lamento no poder ayudarte más, estoy dispuesto a descubrir esto un poco más. Lo mejor es esperar algunos desarrolladores activos de MySQL una vez que dejemos la beta privada;)

jcolebrand
fuente
1

En gran parte, se debe a la seguridad. La excepción para los procedimientos es porque al SQL dinámico dentro del procedimiento se le puede asignar el contexto de seguridad del usuario ejecutor. Esto significa que aunque el motor no sabe qué se va a ejecutar, puede asegurarse de que el usuario tenga acceso a los objetos a los que se hace referencia.

Más allá de eso, puede plantear los problemas feos de lo que podría suceder, si fuera permisible.

dba4life
fuente