跳转到内容

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,允许您自动控制一组查询的事务。

调用过程

[编辑 | 编辑源代码]
华夏公益教科书