使用Clojure连接到Microsoft SQL Server

18

我正在尝试使用Windows身份验证连接到 Microsoft SQL Server 2008 数据库。我已经下载了 MS SQL Server 的 JDBC 驱动程序并将其添加到了 CLASSPATH。

以下是我的 Clojure 代码。无论我做什么,我都会得到 java.sql.SQLException 错误:jdbc:sqlserver 没有合适的驱动程序。

(ns Test)
(def db {:classname "com.microsoft.jdbc.sqlserver.SQLServerDriver"
               :subprotocol "sqlserver"
               :subname "server_name"
               :DatabaseName "database_name"
               :integratedSecurity true
})

(use 'clojure.contrib.sql)
(with-connection db 
      (with-query-results rs ["SELECT * FROM sys.objects"] (prn rs)))

我已经验证了我可以访问数据库,我的类路径是正确的,我下载了正确的JDBC版本。有人能帮我解决这个问题吗。

谢谢。


代码被翻译成Java后会发生什么? - krzysz00
只需添加 :integratedSecurity true 以在 Windows 上使用,就必须将 sqljdbc_auth.dll 添加到 CLASSPATH(例如添加到 /Resources 文件夹中)和 Path Env。 - Dima Fomin
3个回答

18

连接到数据库

在最新的软件版本中(Clojure 1.6+,Microsoft SQL Server 2012和Microsoft JDBC Driver 4.0 for SQL Server),Ash发布的代码只需进行这些修改即可正常工作。我还根据目前对Clojure代码风格指南的了解进行了更新。

(require '[clojure.java.jdbc :as jdbc])
;; you can optionally specify :host and :port to override the defaults
;; of "127.0.0.1" and 1433 respectively:
(def db-spec {:dbtype "mssql"
              :dbname "database-name"
              :user "sql-authentication-user-name"
              :password "password"})

(let [rows (jdbc/query db-spec
                       ["select * from sys.objects  where type = 'U'"])]
  (doseq [row rows] (println (:name row)))))

如果在同一台机器上有多个SQL Server实例,您可以将实例名称作为:host的一部分进行指定,例如(此示例适用于同一台计算机上SQL Server Express的默认实例名称):

:host "localhost\\sqlexpress"

配置 Leiningen

要使 Leiningen 与 Microsoft JDBC Driver 正常配合工作,请将以下内容与 project.clj 中的 defproject 合并:

:dependencies [[org.clojure/java.jdbc "0.6.1"]
               [com.microsoft.sqlserver/mssql-jdbc "6.3.6.jre8-preview"]]

1
我需要手动将我的类路径添加到 project.clj 中,像这样::resource-paths ["C:/Program Files/Java/JDBC/sqljdbc_4.1/enu/sqljdbc41.jar"] - jocull
额外注意事项是,在 :subname 前面的 // 是很重要的。如果没有它,JDBC 连接字符串会以令人困惑的方式中断。 - jocull
1
我使用了lein-localrepo,它似乎不那么具有侵入性。 - Steffen Roller
1
我更新了答案,展示了如何使用:dbtype / :dbname可以使事情变得更简单 - 您不需要类名,子协议或子名称 - 同时删除不必要的with-db-connection包装器(只有在您想要在单个连接中运行多个查询时才需要它)。 - Sean Corfield
2
现在可以从Maven上获取驱动程序,网址为https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc。 - aboy021
显示剩余3条评论

9

找到解决方案

(use 'clojure.contrib.sql)
    (def db {:classname "com.microsoft.sqlserver.jdbc.SQLServerDriver"
                   :subprotocol "sqlserver"
                   :subname "//server-name:port;database=database-name;user=sql-authentication-user-name;password=password"
    })

    ;Add Classpath to your C:\Program Files\Java\JDBC\sqljdbc_3.0\enu\sqljdbc4.jar
    ;Below code demos how to execute a simple sql select query and print it to console
    ;This query will print all the user tables in your MS SQL Server Database
    (with-connection db 
          (with-query-results rs ["select * from sys.objects  where type = 'U'"] 
               (doseq [row rs] (println (:name row)))
    ))

同时更新了维基http://en.wikibooks.org/wiki/Clojure_Programming/Examples/JDBC_Examples#Microsoft_SQL_Server

希望这能对某些人有所帮助。


1
请注意,clojure.contrib.sql已于2011年中停止使用,并被clojure.java.jdbc所取代,详见Alexey的回答。 - Sean Corfield
这句话的意思不应该是“将C:\ Program Files \ Java \ JDBC \ sqljdbc_3.0 \ enu \ sqljdbc4.jar添加到您的CLASSPATH中”吗? - Steffen Roller

2
之前的答案都是正确的,而且都可以正常工作。然而,这篇文章相当古老,现在有更好的选择。因此,我认为更新这篇文章对于那些正在寻找解决方案的人(就像我一样)是有意义的。
事实证明,clojure.java.jdbc已经“稳定”(不再是“活跃”的)。它已经被seancorfield/next.jdbc有效地取代了。
使用next.jdbc相当简单,更多信息可以在项目页面https://github.com/seancorfield/next-jdbc中找到:
代码:
(require '[next.jdbc :as jdbc])
(def db {:dbtype "mssql"
         :dbname "database-name"
         :host "host" ;;optional
         :port "port" ;;optional
         :user "sql-authentication-user-name"
         :password "password"})
(def con (jdbc/get-connection db))
(jdbc/execute! con ["select * from sys.objects  where type = 'U'"])

Leiningen配置

:dependencies [[seancorfield/next.jdbc "1.0.10"]]
               [com.microsoft.sqlserver/mssql-jdbc "7.4.1.jre11"]]

注意:下载适合您的JRE版本的mssql-jdbc驱动程序,并将其放置在Leiningen项目的资源文件夹中,或者在您的project.clj中添加驱动程序路径到:dependencies [<path-here>]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接