Wie verwende ich in MySQL eine C++ Funkion?
-
dein Fehler war, dass du dein Problem falsch beschrieben hast... so hat man es auch falsch verstanden und den Sinn nicht entdeckt... ich dachte bei deinem ersten Posting, du willst aus SQL heraus C++-Funktionen aufrufen... und das macht wirklich keinen Sinn... und ja, einige hier sind durchaus in der Lage, den Sinn einer Sache anzuzweifeln auch wenn der Fragesteller von der Sinnhaftigkeit überzeugt ist... nennt man gemeinhin "Erfahrung"
Hättest du einfach geschrieben, du willst wissen, wie man Variablen in SQL-Anweisungen verwendet wär die Sache deutlich klarer gewesen...
-
zwutz schrieb:
ich dachte bei deinem ersten Posting, du willst aus SQL heraus C++-Funktionen aufrufen... und das macht wirklich keinen Sinn...
Das ist auch das was ich ursprünglich wollte. Also habe ich mich richtig ausgedrückt. Und das macht SINN! Noch nie einen eigenen Passwort-Algorithmus geschrieben? Das ist ein sehr bekanntes Beispiel .. das die Passwörter mit einen eigenen Algorithmus verschlüsselt und in die Datenbank gespeichert werden (und nicht unbedingt vorher verschlüsselt werden, den dieser Anwendungsfall ist nicht immer möglich).
zwutz schrieb:
und ja, einige hier sind durchaus in der Lage, den Sinn einer Sache anzuzweifeln auch wenn der Fragesteller von der Sinnhaftigkeit überzeugt ist... nennt man gemeinhin "Erfahrung"
Erfahrung hin oder her ... es geht einfach nicht. Denn man zweifelt über das was man verstanden hat ... und man hat einfach nicht das verstanden was der Fragesteller gemeint hat. Aus diesem Grund sollte man Fragen bevor man voreilige Schlüsse zieht. Das ist genau wie mit Vorurteile .. als würde ich meinen Kindern erklären das man das nicht machen sollte. Nicht erst losschießen und dann sich darüber Unterhalten. Sondern davor! Das ist ein Grundsatz den jeder einhalten sollte.
Den Fragesteller nützt es über nichts wenn einer sagt es macht kein Sinn. Es sollte lieber entgegenkommen und fragen. Die Frage habe ich schon so oft zitiert:
'was derjenige genau machen möchte, eventuell gibt es ja auch einen anderen Lösungsweg'.zwutz schrieb:
Hättest du einfach geschrieben, du willst wissen, wie man Variablen in SQL-Anweisungen verwendet wär die Sache deutlich klarer gewesen...
Ich habe geschrieben, das ich wissen will wie ich eine Variable auflöse und das ist ja 'verwenden'. Damit ist alles klar.
-
@nixnutz: upps, hab dein Beitrag übersehen. Da ich zu der zeit meinen eigenen Beitrag geschrieben habe :). Werde demnächst darauf antworten, erstmal muss das Essen vorbereitet werden. Dann gegessen usw.
-
@nixnutz:
Ich wollte und möchte immer noch alles auf der SQL-Ebene erledigen.
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.
nixnutz schrieb:
Da passt die Antwort rein, daß Du den MySQL Connector/C++ verwenden könntest. Oder MySQL++ oder die C-API mit "etwas" Casting.
Achso. Das ist der Grund warum mir das angeboten wurde. Dadurch wurde aber leider ein schritt übersprungen und dadurch wird mein Problem nicht gelöst. Vor allem weil ich auch noch das Ergebnis der SQL-Anweisung brauche.
nixnutz schrieb:
Mit anderen Worten: ich mache 1-3 entweder komplett auf dem Client oder komplett auf dem Server. Jetzt dämmert mir langsam, daß Du alles auf dem Server machen wolltest, aber weil Dir ein kleines Stückchen fehlte (CONCAT, dynamic SQL), Du nach 1) für 2) auf den Client wechseln wolltest.
Genau .. ich wollte alles auf dem Server machen. Da ich aber das ganze nicht auflösen konnte wollte ich die Auflösung c++ überlassen, aber ich wollte dennoch die SQL-Anweisung auf der SQL-Ebene ausführen. Zu dieser Zeit habe ich mir aber über das wie noch keine Gedanken gemacht. Da ja noch ein Problem davor stand.
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?
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?
nixnutz schrieb:
Und, hast Du auch verstanden was Du da vorhattest und was Du jetzt machst, um Dir Dynamic SQL innerhalb einer rein server-basierten Lösung zu basteln.
Ich glaube im Prinzip habe ich das verstanden. Einige Sachen sind bestimmt noch nicht ganz verinnerlicht ..
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 ..." ..?
Ich mach ja auch alles auf dem Server ein Escapen ist nur bei Werten notwendig.PS: Ich weiß, von wegen 'Am Nachmittag werde ich antworten'! Immer diese leeren Versprechungen ...
-
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.