跳轉到內容

Haskell/資料庫

來自華夏公益教科書,開放的書籍,開放的世界

Haskell 最流行的資料庫模組是 HDBC。HDBC 在 Haskell 程式和 SQL 關係資料庫之間提供了一個抽象層。這使您能夠一次在 Haskell 中編寫資料庫程式碼,並使其能夠與多個後端 SQL 資料庫一起使用。

HDBC 模仿了 Perl 的 DBI 介面,但它也受到了 Python 的 DB-API v2、Java 中的 JDBC 以及 Haskell 中的 HSQL 的影響。就像 DBI 在 Perl 中需要 DBD 一樣,HDBC 也需要一個驅動模組來工作。

這些 HDBC 後端驅動存在:PostgreSQL、SQLite 和 ODBC(用於 Windows 和 Unix/Linux/Mac)。MySQL 是最流行的開源資料庫,並且有兩個用於 MySQL 的驅動程式:HDBC-mysql(原生)和 HDBC-odbc(ODBC)。MySQL 使用者可以在任何支援 MySQL 的平臺上使用 ODBC 驅動程式,包括 Linux。

使用 ODBC 的一個優點是 SQL 語句的語法不受不同型別的資料庫引擎的影響。如果需要從一個數據庫遷移到另一個數據庫,這將提高應用程式的可移植性。使用 ODBC 的相同理由適用於其他商業資料庫(如 Oracle 和 DB2)。

PostgreSQL 或 SQLite

[編輯 | 編輯原始碼]

有關更多資訊,請參閱 HDBC 常見問題解答

原生 MySQL

[編輯 | 編輯原始碼]

原生 ODBC-mysql 庫需要 C MySQL 客戶端庫存在。

您可能需要 包裝您的資料庫訪問 以防止執行時錯誤。

ODBC/MySQL

[編輯 | 編輯原始碼]

使 HDBC 透過 ODBC 與 MySQL 一起工作有點複雜,尤其是當您沒有 root 許可權時。

  • 如果您的平臺還沒有提供 ODBC 庫(大多數平臺都有),請安裝 Unix-ODBC。有關更多資訊,請參見 這裡
  • 安裝 MySQL-ODBC 聯結器。有關更多資訊,請參見 這裡
  • 安裝 Database.HDBC 模組
  • 安裝 Database.HDBC.ODBC 模組
  • 將 mysql 驅動程式新增到 odbcinst.ini 檔案(位於 $ODBC_HOME/etc/)和 $HOME/.odbc.ini 中的資料來源。
  • 建立測試程式

由於 ODBC 驅動程式預設情況下使用共享庫安裝,因此您需要以下環境變數

export LD_LIBRARY_PATH=$ODBC_HOME/lib

如果您不喜歡新增額外的環境變數,則應嘗試使用靜態庫選項啟用編譯 ODBC。

接下來的任務是編寫一個簡單的測試程式,該程式連線到資料庫並列印所有表的名稱,如下所示。

您可能需要 包裝您的資料庫訪問 以防止執行時錯誤。

  module Main where
  import Database.HDBC.ODBC
  import Database.HDBC
  main =
    do c  <- connectODBC "DSN=PSPDSN"
       xs <- getTables c
       putStr $ "tables "++(foldr jn "." xs)++"\n"
    where jn a b = a++" "++b

一般工作流程

[編輯 | 編輯原始碼]

連線和斷開連線

[編輯 | 編輯原始碼]

任何資料庫操作的第一步都是連線到目標資料庫。這是透過驅動程式特定的連線 API 完成的,該 API 的型別為

 String -> IO Connection

給定一個連線字串,連線 API 將返回 Connection 並將您置於 IO monad 中。

儘管大多數程式將在它們超出範圍或程式結束時垃圾收集您的連線,但顯式斷開與資料庫的連線是一個好習慣。

 conn->Disconnect

執行查詢

[編輯 | 編輯原始碼]

執行查詢通常涉及以下步驟

  • 準備語句
  • 使用繫結變數執行語句
  • 獲取結果集(如果有)
  • 完成語句

HDBC 提供了兩種用於繫結變數和返回結果集的方法:[ SqlValue ][ Maybe String ]。使用 [ Maybe String ] 時,需要使用以 s 為字首的函式,而不是 [ SqlValue ][ SqlValue ] 允許您使用強型別資料,如果型別安全在您的應用程式中非常重要;否則,當處理大量資料庫查詢時,[ Maybe String ] 更加方便。使用 [ Maybe String ] 時,您假設資料庫驅動程式將執行自動資料轉換。請注意,這種便利會帶來效能成本。

有時,當查詢很簡單時,會有一些簡化的 API 將多個步驟包裝在一個步驟中。例如,RunsRun 是“準備和執行”的包裝器。quickQuery 是“準備、執行和獲取所有行”的包裝器。

執行 SQL 語句

[編輯 | 編輯原始碼]

資料庫事務由commitrollback控制。但是請注意,某些資料庫(例如 mysql)不支援事務。因此,每個查詢都處於其原子事務中。

HDBC 提供withTransaction,允許您自動控制一組查詢的事務。

呼叫過程

[編輯 | 編輯原始碼]
華夏公益教科書