2016-05-04 15 views
1

Der REST-Aufruf sendet die branchId und emplId an diese Methode exec-sql-file. Ich übergebe diese als Parameter. Ich bin nicht in der Lage, die SQL-Anweisung auszuführen, wenn ich branch_id = @branchid und empl_id = @emplid überlasse. Aber wenn ich die branch_id = 'BR101' und empl_id = 123456 fest codiere, dann funktioniert es. Irgendwelche Vorschläge, wie man die branch_Id und empl_Id in meine some-statements.sql bekommt?Laden von SQL-Anweisungen aus einer Datei mit clojure.java.jdbc

(defn exec-sql-file 
    [branchid emplid] 
    (sql/with-db-connection (db-conn) 
    (sql/db-do-prepared conn 
     [branchid emplid (slurp (resource "sql/some-statements.sql"))]))) 

some-statements.sql hat diese Abfrage

DELETE from customer where branch_id = @branchid and empl_id = @emplid; 

ich dies als

(exec-sql-file "BR101" 123456) 

von REPL bin Ausführung ich den Code-Schnipsel aus dem unten stehenden Beitrag zu greifen.

Is it possible to patch load SQL statements from a file using clojure.java.jdbc?

Antwort

0

Es gibt keine einfache Möglichkeit, dies als Ansatz zu tun, müssen Sie Parameter, um mehrere SQL-Anweisungen in einem Lauf zu bieten haben. Ein weiteres Problem ist, dass Javas PreparedStatement (unter der Haube von clojure.java.jdbc) benannte Parameter nicht unterstützt, also selbst wenn Parameter für mehrere SQL-Anweisungen mit einer einzigen vorbereiteten Anweisung erstellt würden, müsste für jeden Platzhalter (?) angegeben werden.

Ich würde folgende Lösungen vorschlagen:

  • Verwendung mehrerer Anweisungen vorbereitet (so getrennte clojure.java.jdbc/execute! Anrufe) für jede der SQL-Anweisung Sie in einer einzelnen Transaktion (jeder SQL gewickelt ausführen wollen könnte von einem gelesen werden separate Datei). Sie können auch eine Hilfsbibliothek wie YeSQL verwenden, um das Laden Ihrer SQL-Anweisungen aus externen Dateien zu ermöglichen und sie als Funktionen anzuzeigen, die Sie als normale Clojure-Funktionen bezeichnen könnten. Es wäre einfach, aber wenn Sie die Anzahl der Anweisungen, die Sie ausführen möchten, ändern, dann müssen Sie Ihren Code ändern

  • erstellen Sie eine gespeicherte Prozedur und rufen Sie von Clojure die Bereitstellung der Parameter - dies wird eine Schnittstelle für einige definieren DB-Logik, die auf der DB-Seite definiert wird. Wenn Sie die Schnittstelle Ihrer gespeicherten Prozedur nicht ändern, können Sie ihre Implementierung ändern, ohne Ihren Clojure-Code zu ändern oder Ihre eigene Logik der Interpolation benannter Parameter in Ihre "Multistatement" SQL-Datei zu implementieren. Das Problem besteht darin, die Werte der Parameter angemessen zu umgehen, damit Ihr Code nicht anfällig für SQL-Injection ist. Ich würde diese Lösung abraten.

+0

Danke für die Antwort Piotrek. Die Datei some-statements.sql enthält auch Funktionen zum Aktualisieren und Einfügen, und die Klausel where ist branchid und emplid für alle SQL-Anweisungen. – Aiswa

+0

@Aiswa, es war mir aus der Frage nicht offensichtlich. Ich habe meine Antwort aktualisiert, um diese Anforderung zu berücksichtigen. –

+0

Ich habe das auf andere Weise versucht. Bitte lassen Sie mich wissen, wenn ich etwas falsch mache. – Aiswa

Verwandte Themen