Wie verwende ich in MySQL eine C++ Funkion?
-
Beschreib einfach das, was du ursprünglich lösen willst, und nicht eine Idee die du hattest wie man es vielleicht lösen könnte. Speziell wenn diese Idee recht seltsam ("eigenwillig"), und noch dazu undurchführbar ist, werden die Leute reichlich verwirrt sein, und u.U. nicht wissen können was du eigentlich wolltest.
BTW: zu behaupten dass dich die meisten schon richtig verstanden haben bringt dich nicht weiter. Offensichtlich hast du in deiner Fragestellung etwas gröber falsch gemacht, denn die Sache die du eigentlich beantwortet haben wolltest ist so einfach, dass in kürzester Zeit eine passende Antwort hätte kommen müssen.
-
mysql+c++ schrieb:
@nixnutz:
Ich wollte und möchte immer noch alles auf der SQL-Ebene erledigen.Ja, das habe ich inzwischen kapiert.
mysql+c++ schrieb:
Um das mit deine Übersicht zu erklären:
- Lese "Log" aus
- Erstelle neue Anfrage aus Werten von "Log"
- Sende neue Anfrage
Der Gedanke war so (das geschieht alles aus einer Stored Procedures):
1. auf SQL
2. mittels C++ Funktion, da ich die Variablen nicht auflösen konnte.
3. auf dem SQL in der ProzedurEin Client wird also nicht gebraucht.
Hmm, ja... Die C++-Funktion muß ja auch irgendwo liegen. Selbst wenn sie durch den Server bereitgestellt wird, muß der Server aus dem SQL-Kontext in den Kontext einer externen C++-Funktion wechseln und das dürfte "teuer" sein.
mysql+c++ schrieb:
nixnutz schrieb:
Die Verwendung eines Prepared Statements siehst Du nicht als Umweg an, weil Du damit deine rein server-basierte Lösung bekommst. Über die Krücke der Prepared Statements baust Du Dir Dynamic SQL im MySQL Server. Das ist Dreck ! Wer Prepared Statements nur verwendet, um damit Dynamic SQL zu relalisieren sollte sich darüber im Klaren sein, daß er sie vergewaltigt. Bevor Du wieder einen Anfall bekommst: bis heute gibt es keine andere Möglichkeit eine rein server-basierte (ohne UDF) Lösung für dein Problem zu erstellen.
Was würdest du Vorschlagen? Es gibt doch keine andere Möglichkeit. Also muss
ich den Geschwindigkeitsnachteil hinnehmen, oder etwa nicht?Du willst Dynamic SQL. Stand heute geht das nur über den Umweg PREPARE + EXECUTE, weil MySQL dir bislang keinen Ausdruck anbietet mit dem Du in einem Schritt Dynamic SQL bekommst. Das große Warten auf EXECUTE IMMEDIATE...
Alles was ich sagen will ist, daß man Dynamic SQL nicht grundsätzlich mit Prepared Statements verbinden muss. Daß Du PS benutzen musst bei MySQL, halte ich für einen MySQL-spezifischen Hack. PS an sich haben nichts mit Dynamic SQL zu tun.
Wie die Performance von einem zukünftigen EXECUTE IMMEDIATE mit im Vergleich zu der des aktuell notwendigen PREPARE + EXECUTE "Hacks" ausfallen wird, mag ich nicht zu beurteilen. Ich bin kein Hellseher.
Vielleicht einer der größten Pferdefüsse bei PS mit Stand heute ist, daß PS natürlich Ressourcen allokieren (und blockieren) und die lieben Benutzer gerne vergessen die belegten Ressourcen so schnell wie möglich freizugeben, weil die Freigabe ja sowieso irgendwann implizit von der Datenbank gemacht wird...
mysql+c++ schrieb:
nixnutz schrieb:
Was Du eigentlich willst ist EXECUTE IMMEDIATE:
EXECUTE IMMEDIATE kann doch nicht in Stored Procedures verwendet werden .. ? Also kann ich das auch verwenden, oder etwa doch?
http://forge.mysql.com/worklog/task.php?id=2793 , erster Satz:
"Introduce a convenient syntax for Dynamic SQL in stored procedures:"Status des geplanten Features: "Affects: Server-6.x — Status: In-Design — Priority: Medium"
mysql+c++ schrieb:
nixnutz schrieb:
Wenn Du alle Schritte auf dem Client machst, dann ist es nicht zwingend notwendig Prepared Statements zu benutzen. Bei Ausführung aller Schritte auf dem Client, kannst Du auch ein "normales" Statement verwenden.
Hier meinst du sicherlich "Beim Ausführen aller Schritte auf dem Server ..." ..?
Nein. Übertrage das Beispiel vom letzten Posting mit '"USE " EXAMPLE_DB' auf 2) und Du hast es.
mysql+c++ schrieb:
Ich mach ja auch alles auf dem Server ein Escapen ist nur bei Werten notwendig.
Es kommt darauf an. Grundsätzlich bist Du als Entwickler dafür zuständig Eingabedaten zu bereinigen, damit kein Unfug passiert. Wenn Du mit Prepared Statements arbeitest und Du entweder eine PS-API verwendet, die direkt auf die PS von MySQL zurückgeht (keine Emulation!) oder Du auf der SQL-Ebene im Server bleibst brauchst Du Werte nicht zu escapen, weil dies implizit gemacht wird.
Du musst die Fälle wieder aufspalten, am Ende ist auch dein Fall aufgeführt:
a) Client-Applikation (MULTI_STATEMENT-Option aktiviert) ohne Prepared Statements
meindatum = "; DELETE FROM t1; ";
meinsql = "SELECT * FROM TABLE t1" + [meindatum] + "WHERE t1.c1 = 1"
--> SQL-Injection bei Ausführungb) Client-Applikation (MULTI_STATEMENT-Option deaktiviert = VOREINSTELLUNG(!)) ohne Prepared Statements
meindatum = "; DELETE FROM t1; ";
meinsql = "SELECT * FROM TABLE t1" + [meindatum] + "WHERE t1.c1 = 1"
--> Syntaxfehler bei Ausführungc) Client Applikation mit Prepared Statements über API:
meinsql = "SELECT * FROM TABLE t1 ? WHERE t1.c1 = 1"
--> Syntaxfehler beim Vorbereitenmeindatum = ", t2";
meinsql = "SELECT * FROM TABLE t1 " + meindatum + " WHERE t1.c1 = ?"
---> Syntax gültig, lässt sich vorbereiten
---> bind(1, "mein_; DROP TABLE t1;")
---> Ausführung klappt, weil dank PS-API implizit escaped wurde, keine Injectiond) Dein Fall, Stored Procedure mit Prepared Statement für Dynamic SQL
Es ist deine Aufgabe Eingabedaten zu bereinigen! Das wird Dir natürlich nie passieren...
SET @meindatum = ", geheime_spalte";
SET @meinsql = CONCAT("SELECT c1 ", @meindatum, " FROM t1");
PREPARE stmt1 FROM @meinsql;
EXECUTE stmt1;... und das natürlich auch nicht, weil...
CREATE TABLE t2(c1 VARCHAR(64));
INSERT INTO t2(c1) VALUES (", geheime_spalte");
SELECT c1 FROM t2 INTO @meindatum;
SET @meinsql = CONCAT("SELECT c1 ", @meindatum, " FROM t1");
PREPARE stmt1 FROM @meinsql ;
EXECUTE stmt1;... Du selbstverständlich darauf achtest keinem Eingabedatum zu vertrauen - auch nicht dem aus deiner Tabelle t2 - und Du sofort reagieren würdest.
Aber das schweift ab, Deine Frage bezog sich auf das Escapen:
CREATE TABLE t1(c1 INT, c2 CHAR(1))
INSERT INTO t1(c1, c2) VALUES (1, "a");
PREPARE stmt1 FROM "SELECT * FROM t1 WHERE c2 = ?";SET @meindatum = "a";
EXECUTE stmt1 USING @meindatum -> ErgebnisSET @meindatum = '"a"';
EXECUTE stmt USING @meindatum -> kein Ergebnis (korrekt)SET @meindatum = '"a"; DELETE FROM t1'
EXECUTE stmt USING @meindatum -> kein Ergebnis (korrekt)Warum ergebene die letzten beiden weder einen Fehler noch eine SQL-Injection? Weil die Datenbank weiß, daß Du Werte einfügen willst und schlau genug ist das notwendige "escaping" implizit zu machen, damit keine Probleme auftreten.
Ulf
-
Jo, Parameter verwenden ist natürlich viel besser als Strings escapen.
-
@hustbaer: geht klar das werde ich berücksichtigen
@nixnutz:nixnutz schrieb:
Es kommt darauf an. Grundsätzlich bist Du als Entwickler dafür zuständig Eingabedaten zu bereinigen, damit kein Unfug passiert. Wenn Du mit Prepared Statements arbeitest und Du entweder eine PS-API verwendet, die direkt auf die PS von MySQL zurückgeht (keine Emulation!) oder Du auf der SQL-Ebene im Server bleibst brauchst Du Werte nicht zu escapen, weil dies implizit gemacht wird.
Ja. Bei meiner Log Tabelle wurde beim Eintragen jetzt alles überprüft. Solche extreme wie "DROP table1" gibt es bei mir sowieso nicht und kann es auch nicht geben.
nixnutz schrieb:
Nein. Übertrage das Beispiel vom letzten Posting mit '"USE " EXAMPLE_DB' auf 2) und Du hast es.
geht klar.
Da wir gerade dabei sind. Ich hänge gerade an einem anderen Problem. Was aber sehr ähnlich ist. Erstmal ein paar Worte im Voraus:
Ich habe ja eine Log-Tabelle ... die wird mit Hilfe von Triggern gefüllt. Nun möchte ich die Trigger mit einer Prozedur erstellen. Wie ist das am besten zu realisieren? Einen Ansatz lass ich jetzt einfach mal weg.
-
Wenn du mit "Prozedur" eine "stored procedure" meinst, dann kommt IMO auch nur dynamic SQL in Frage. Weil vermutlich ein Teil der hier variabel sein muss der Prozedur-Name ist, und den kann man auch nicht als "?-Parameter" übergeben.
-
hustbaer schrieb:
Wenn du mit "Prozedur" eine "stored procedure" meinst, dann kommt IMO auch nur dynamic SQL in Frage.
Ja meine ich. Es soll auch wieder alles auf der SQL-Ebene geschehen.
hustbaer schrieb:
Weil vermutlich ein Teil der hier variabel sein muss der Prozedur-Name ist, und den kann man auch nicht als "?-Parameter" übergeben.
Ich habe eine einzige Prozedur die den SQL Befehl zusammenstellt. Hier zu Info noch:
Ja, ein Teil ist wieder Variable. Aber wenn ich Prepare Statement benutze, dann kommt die Meldung: "This command is not supported in the prepared statement protocol yet"
-
Er. Ich meinte natürlich der Trigger-Name wird wohl variabel sein müssen (nicht der Name der stored procedure), sorry
-
hustbaer schrieb:
Er. Ich meinte natürlich der Trigger-Name wird wohl variabel sein müssen (nicht der Name der stored procedure), sorry
Genau .. der Trigger-Name wird aus Präfix + Tabellen-Name erstellt. Bezugsquelle ist hier auch INFORMATION_SCHEMA.
Hast du eine Idee wie das gemacht werden könnte? Den Namen und SQL-Befehl habe ich schon fertig. Nur das abfeuern fehlt.
-
mysql+c++ schrieb:
hustbaer schrieb:
Er. Ich meinte natürlich der Trigger-Name wird wohl variabel sein müssen (nicht der Name der stored procedure), sorry
Genau .. der Trigger-Name wird aus Präfix + Tabellen-Name erstellt. Bezugsquelle ist hier auch INFORMATION_SCHEMA.
Hast du eine Idee wie das gemacht werden könnte? Den Namen und SQL-Befehl habe ich schon fertig. Nur das abfeuern fehlt.Nö.
MySQL unterstützt dynamic SQL anscheinend nicht wirklich. Zumindest hab' ich nixe zu dem Thema gefunden, ausser eben die prepared statements. Kenne mich mit MySQL auch nicht so toll aus. Nimm SQL Server Express
-
hustbaer schrieb:
Nö.
MySQL unterstützt dynamic SQL anscheinend nicht wirklich. Zumindest hab' ich nixe zu dem Thema gefunden, ausser eben die prepared statements. Kenne mich mit MySQL auch nicht so toll aus. Nimm SQL Server ExpressHehe .. nimm einfach eine andere Datenbank ist einfach gesagt.