SQL dynamique dans les routines stockées MySQL

Réponses:

8

Le simple fait d'entendre la question me fait penser à deux aspects:

ASPECT # 1: Les fonctions sont censées être DETERMINISTIQUES

Si tel est le cas, cela implique qu'une fonction doit présenter les mêmes données de retour de manière cohérente pour un ensemble de paramètres donné, PAS DE QUESTION LORSQUE VOUS APPELER LA FONCTION.

Maintenant, imaginez une fonction qui produit une réponse différente en raison de la collecte de données à différents moments de la journée sur la base de SQL statique dans la fonction. Dans un sens, cela peut toujours être considéré comme DETERMINISTIQUE si vous interrogez le même ensemble de tables et de colonnes à chaque fois, étant donné le même ensemble de paramètres.

Et si vous pouviez changer les tables sous-jacentes d'une fonction via Dynamic SQL? Vous violez la définition d'une fonction DETERMINISTIQUE.

Notez que MySQL a ajouté cette option dans /etc/my.cnf

log-bin-trust-function-creators

Bien que cela puisse être une simplification excessive, cela permet aux fonctions d'être autorisées à écrire des données dans des journaux binaires sans appliquer strictement la propriété DETERMINISTIC.

ASPECT # 2: Les déclencheurs doivent pouvoir être annulés

  • Pouvez-vous imaginer un déclencheur avec tous les mêmes comportements qu'une fonction, puis introduire Dynamic SQL dans le mix?
  • Pouvez-vous imaginer essayer d'appliquer MVCC (Multiversion Concurrecy Control) contre Dynamic SQL après avoir appliqué MVCC à la table de base à laquelle le déclencheur était destiné?

Vous auriez essentiellement des données qui croissent de façon quadratique (même exponentielle) uniquement dans MVCC seul. Le processus de gestion de la restauration de SQL avec des déclencheurs qui peuvent être non DETERMINISTIQUES serait pour le moins complexe et impie.

À la lumière de ces deux aspects, je suis sûr que les développeurs MySQL ont pensé à ces choses et les ont rapidement rejetées en imposant des restrictions.

Alors, pourquoi lever la restriction des procédures? Autrement dit, il n'y a aucune préoccupation concernant les propriétés DETERMINISTIQUES ou Rollback.

RolandoMySQLDBA
la source
3
Cela ne peut pas être aussi "impie complexe" si d'autres SGBD peuvent très bien prendre en charge MVCC et SQL dynamique dans les déclencheurs.
a_horse_with_no_name
1
En fait, @a_horse_with_no_name, vous avez raison. Pour Oracle et PostgreSQL, un complexe impie a été codé. +1 pour votre commentaire. MySQL a le handicap de gérer plusieurs moteurs de stockage, donc la restauration et le déterminisme peuvent nécessiter un chevauchement des opérations du moteur de stockage. C'est un peu effrayant. Peut-être que quelqu'un aura le courage de pousser le "complexe impie" dans InnoDB dans son intégralité. Encore plus souhaitable serait de créer une implémentation de déclencheur spécifique au moteur de stockage de telle manière qu'elle ne permette pas de mélanger les moteurs de stockage dans la même requête.
RolandoMySQLDBA
5

C'est une excellente question, mais je ne connais pas la réponse. J'imagine que cela va devoir rejoindre l'équipe interne, mais je ne sais pas s'ils seront importants dans ce site. En attendant, je peux vous aider à déduire quelques réponses.

Pour commencer, je vois ceci:

Le cache de déclenchement ne détecte pas lorsque les métadonnées des objets sous-jacents ont changé. Si un déclencheur utilise une table et que la table a changé depuis le chargement du déclencheur dans le cache, le déclencheur fonctionne à l'aide des métadonnées obsolètes.

Ce qui me fait penser que cela a quelque chose à voir avec ça. Il ne recompilera pas SQL s'il ne surveille même pas les métadonnées. Ce qui signifie que c'est une préoccupation pour le moteur.

De la même façon, quand je lis ce bloc, je pense la même chose (moteur):

Pour éviter les problèmes d'interaction entre les threads du serveur, lorsqu'un client émet une instruction, le serveur utilise un instantané des routines et des déclencheurs disponibles pour l'exécution de l'instruction. En d'autres termes, le serveur calcule une liste de procédures, de fonctions et de déclencheurs pouvant être utilisés pendant l'exécution de l'instruction, les charge, puis procède à l'exécution de l'instruction. Cela signifie que pendant l'exécution de l'instruction, elle ne verra pas les modifications apportées aux routines effectuées par d'autres threads.

Donc, dans l'ensemble, je ne sais pas exactement pourquoi ils ne le permettent pas, mais je peux deviner. Désolé de ne pas pouvoir vous aider davantage, je suis prêt à en discuter davantage. Le mieux est d'espérer des développeurs MySQL actifs une fois que nous aurons quitté la bêta privée;)

jcolebrand
la source
1

En grande partie, cela est dû à la sécurité. L'exception pour les procédures est que le SQL dynamique dans la procédure peut être affecté au contexte de sécurité de l'utilisateur en cours d'exécution. Cela signifie que même si le moteur ne sait pas quoi va être exécuté, il peut s'assurer que l'utilisateur est autorisé à accéder aux objets référencés.

Au-delà de cela, vous pouvez soulever les problèmes laids de ce qui pourrait arriver, si cela était permis.

dba4life
la source