Dynamisches SQL in in MySQL gespeicherten Routinen


Antworten:


8

Wenn ich nur die Frage höre, fallen mir zwei Aspekte ein:

ASPEKT 1: Funktionen sollten DETERMINISTISCH sein

Wenn dies der Fall ist, bedeutet dies, dass eine Funktion dieselben Rückgabedaten für einen bestimmten Satz von Parametern konsistent darstellen sollte, unabhängig davon, wann Sie die Funktion aufrufen.

Stellen Sie sich nun eine Funktion vor, die aufgrund der Erfassung von Daten zu unterschiedlichen Tageszeiten basierend auf statischem SQL in der Funktion eine andere Antwort liefert. In gewissem Sinne kann dies immer noch als DETERMINISTISCH betrachtet werden, wenn Sie bei gleichen Parametern jedes Mal denselben Satz von Tabellen und Spalten abfragen.

Was wäre, wenn Sie die zugrunde liegenden Tabellen einer Funktion über Dynamic SQL ändern könnten? Sie verletzen die Definition einer DETERMINISTIC-Funktion.

Beachten Sie, dass MySQL diese Option in /etc/my.cnf hinzugefügt hat

log-bin-trust-function-creators

Obwohl dies eine zu starke Vereinfachung sein mag, können Funktionen Daten in Binärprotokolle schreiben, ohne die DETERMINISTIC-Eigenschaft strikt zu erzwingen.

ASPECT # 2: Trigger sollten rückgängig gemacht werden können

  • Können Sie sich einen Trigger vorstellen, der die gleichen Verhaltensweisen wie eine Funktion aufweist und dann Dynamic SQL in den Mix einführt?
  • Können Sie sich vorstellen, MVCC (Multiversion Concurrecy Control) auf Dynamic SQL anzuwenden, nachdem MVCC auf die Basistabelle angewendet wurde, für die der Trigger bestimmt war?

Sie würden im Wesentlichen Daten haben, die nur in MVCC quadratisch (sogar exponentiell) wachsen. Der Prozess der Verwaltung des Rollbacks von SQL mit Triggern, die nicht DETERMINISTISCH sein können, wäre, gelinde gesagt, gottlos komplex.

In Anbetracht dieser beiden Aspekte bin ich sicher, dass MySQL-Entwickler über diese Dinge nachgedacht und sie schnell durch Auferlegung von Einschränkungen verworfen haben.

Warum also die Beschränkung für Verfahren aufheben? Einfach ausgedrückt, gibt es keine Bedenken hinsichtlich der DETERMINISTISCHEN Eigenschaften oder des Rollbacks.


2
Kann nicht so "gottlos komplex" sein, wenn andere DBMS MVCC und dynamisches SQL in Triggern sehr gut unterstützen können.
a_horse_with_no_name

1
Eigentlich, @a_horse_with_no_name, hast du recht. Für Oracle und PostgreSQL wurde ein gottloser Komplex programmiert. +1 für deinen Kommentar. MySQL hat das Handicap, mit mehreren Speicher-Engines umzugehen, sodass Rollback und Determinismus möglicherweise eine Überlappung der Speicher-Engine-Operationen erfordern. Das ist ein bisschen beängstigend. Vielleicht hat jemand den Mut, "gottlose Komplexe" vollständig in InnoDB zu integrieren. Noch wünschenswerter wäre es, eine Speicher-Engine-spezifische Trigger-Implementierung zu erstellen, die es nicht ermöglicht, Speicher-Engines in derselben Abfrage zu mischen.
RolandoMySQLDBA

5

Das ist eine großartige Frage, aber ich kenne die Antwort nicht. Ich stelle mir vor, das muss ins Internalteam, aber ich weiß nicht, dass sie auf dieser Seite groß rauskommen werden. In der Zwischenzeit kann ich Ihnen helfen, einige Antworten abzuleiten.

Für den Anfang sehe ich Folgendes:

Der Trigger-Cache erkennt nicht, ob sich Metadaten der zugrunde liegenden Objekte geändert haben. Wenn ein Trigger eine Tabelle verwendet und sich die Tabelle geändert hat, seit der Trigger in den Cache geladen wurde, verwendet der Trigger die veralteten Metadaten.

Was mich denken lässt, dass das etwas damit zu tun hat. SQL wird nicht neu kompiliert, wenn nicht einmal die Metadaten überwacht werden. Was bedeutet, dass es sich um einen Motor handelt.

Aus dem gleichen Grund denke ich, wenn ich diesen Block lese, dasselbe (Motor):

Um Interaktionsprobleme zwischen Serverthreads zu vermeiden, verwendet der Server beim Ausgeben einer Anweisung durch einen Client eine Momentaufnahme der für die Ausführung der Anweisung verfügbaren Routinen und Trigger. Das heißt, der Server berechnet eine Liste von Prozeduren, Funktionen und Triggern, die während der Ausführung der Anweisung verwendet werden können, lädt sie und fährt dann mit der Ausführung der Anweisung fort. Dies bedeutet, dass während der Ausführung der Anweisung keine Änderungen an Routinen angezeigt werden, die von anderen Threads ausgeführt werden.

Alles in allem bin ich mir nicht ganz sicher, warum sie es nicht zulassen, aber ich kann es mir vorstellen. Tut mir leid, dass ich dir nicht mehr helfen kann, ich bin offen dafür, das noch etwas zu klären. Das Beste ist, auf einige aktive MySQL-Entwickler zu hoffen, sobald wir die private Beta verlassen haben;)


1

Zum größten Teil liegt es an der Sicherheit. Die Ausnahme für Prozeduren besteht darin, dass der dynamischen SQL innerhalb der Prozedur der Sicherheitskontext des ausführenden Benutzers zugewiesen werden kann. Dies bedeutet, dass die Engine, obwohl sie nicht weiß, was ausgeführt werden soll, sicherstellen kann, dass der Benutzer auf die referenzierten Objekte zugreifen darf.

Darüber hinaus können Sie die hässlichen Fragen aufwerfen, was passieren könnte, wenn es zulässig wäre.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.