使用clojure.java.jdbc从文件加载SQL语句

时间:2016-05-04 13:43:30

标签: jdbc clojure

REST调用正在将branchId和emplId发送到此exec-sql-file方法。我将这些作为参数传递。当我传递branch_id = @branchid和empl_id = @emplid时,我无法执行SQL语句。但是当我硬编码branch_id =' BR101'和empl_id = 123456然后它正在工作。有关如何在some-statements.sql中获取branch_Id和empl_Id的任何建议吗?

z+=4

some-statements.sql有此查询

(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"))])))

我正在从REPL执行此操作

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

我从下面的帖子中获取了代码段。

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

1 个答案:

答案 0 :(得分:0)

没有简单的方法可以做到这一点,因为您的方法要求您必须在一次运行中为多个SQL语句提供参数。另一个问题是Java PreparedStatement(由clojure.java.jdbc引用)并不支持命名参数,因此即使使用单个预准备语句完成多个SQL语句的参数,必须为每个占位符(?)提供。

我建议遵循以下解决方案:

  • 对于要在单个事务中执行的每个SQL语句使用多个预准备语句(因此单独的clojure.java.jdbc/execute!调用)(每个SQL都可以从单独的文件中读取)。您还可以使用一些辅助库(如YeSQL)从外部文件加载SQL语句,并将它们作为普通Clojure函数调用的函数公开。这很简单但是如果你改变你想要执行的语句数量,那么你需要更改你的代码

  • 创建一个存储过程并从提供参数的Clojure中调用它们 - 这将为某些DB逻辑定义一个接口,该接口将在DB端定义。除非您更改存储过程的界面,否则可以在不更改Clojure代码或重新部署的情况下修改其实现

  • 实现您自己的逻辑,将命名参数插入您的"多语句" SQL文件。问题是适当地逃避参数'值,因此您的代码不易受SQL注入攻击。我会劝阻这个解决方案。