3.数据库 | 3. Databases

3 数据库

3.1数据库

如果您需要访问关系数据库,例如sqlservermysqlpostgresoraclecybase等使用Erlang的ODBC接口的应用二郎是去了解它的好方法。

Erlang ODBC应用程序应该适用于任何具有ODBC驱动程序的关系数据库。但目前它只是经常测试sqlserverpostgres

3.2数据库独立性

Erlang ODBC接口与数据库主体无关,因此使用该接口的erlang程序可以在不改变数据库的情况下运行。但是,当使用SQL时,编写数据库相关程序是可能的。尽管SQL是一种ANSI标准,意味着与数据库无关,但不同的数据库拥有对SQL定义自己数据类型的专有扩展。如果您遵守ANSI数据类型,您将最大限度地减少问题。但不幸的是,并不能保证所有的数据库实际上都等价地处理ANSI数据类型。例如,安装Oracle Enterprise release 8.0.5.0.0 for unixwill将接受使用ANSI数据类型创建表列integer,但是当从该列中检索值时,驱动程序报告它是类型的,SQL_DECIMAL(0, 38)而不是SQL_INTEGER您所期望的。

另一个障碍是,一些驱动程序不支持可滚动游标,这种游标的效果是遍历结果集的唯一方法是顺序执行,其次是从第一行到最后一行,并且一旦通过行就不能返回。这意味着界面中的某些功能不能与某些驱动程序一起使用。类似的问题是,并非所有的驱动程序支持“行数”为select查询,从而导致该函数select_count/[3,4]将返回{ok, undefined},而不是{ok, NrRows}那里NrRows是在结果集的行数。

3.3数据类型

以下是ANSI数据类型的列表。有关详细信息,请转至ANSI标准文档。其他数据类型的使用当然是可能的,但您应该知道,这会使您的应用程序依赖于当前正在使用的数据库。

  • CHARACTER (size), CHAR (size)

  • NUMERIC(精度,比例),DECIMAL(精度,比例),DEC(精度,比例)精度 - 总位数,比例 - 小数位总数

  • 整数,int,SMALLINT

  • FLOAT (precision)

  • 双精度

  • CHARACTER VARYING(size), CHAR VARYING(size)

当使用sql_query/2,3输入数据时,这些值将始终为字符串格式,因为它们是SQL查询的一部分。例:

odbc:sql_query(Ref, "INSERT INTO TEST VALUES(1, 2, 3)").

注意,当要输入的数据的值是字符串时,必须用'.例如:

odbc:sql_query(Ref, "INSERT INTO EMPLOYEE VALUES(1, 'Jane', 'Doe', 'F')").

您还可以使用param_query/[3,4]然后输入数据将具有与列的ODBC类型相对应的Erlang类型。See ODBC to Erlang mapping

从表中选择数据时,所有数据类型都会作为ODBC数据类型从数据库返回到ODBC驱动程序。下表显示了这些数据类型与ErlangAPI返回的数据之间的映射。

ODBC数据类型Erlang数据类型
SQL_CHAR(size)String | Binary (configurable)
SQL_WCHAR(size)Unicode binary encoded as UTF16 little endian.
SQL_NUMERIC(p,s) when (p >= 0 and p <= 9 and s == 0)Integer
SQL_NUMERIC(p,s) when (p >= 10 and p <= 15 and s == 0) or (s <= 15 and s > 0)Float
SQL_NUMERIC(p,s) when p >= 16String
SQL_DECIMAL(p,s) when (p >= 0 and p <= 9 and s == 0)Integer
SQL_DECIMAL(p,s) when (p >= 10 and p <= 15 and s == 0) or (s <= 15 and s > 0)Float
SQL_DECIMAL(p,s) when p >= 16String
SQL_INTEGERInteger
SQL_SMALLINTInteger
SQL_FLOATFloat
SQL_REALFloat
SQL_DOUBLEFloat
SQL_VARCHAR(size)String | Binary (configurable)
SQL_WVARCHAR(size)Unicode binary encoded as UTF16 little endian.

ODBC数据类型Erlang数据类型
SQL_TYPE_DATEString
SQL_TYPE_TIMEString
SQL_TYPE_TIMESTAMP{{YY, MM, DD}, {HH, MM, SS}}
SQL_LONGVARCHARString | Binary (configurable)
SQL_WLONGVARCHAR(size)Unicode binary encoded as UTF16 little endian.
SQL_BINARYString | Binary (configurable)
SQL_VARBINARYString | Binary (configurable)
SQL_LONGVARBINARYString | Binary (configurable)
SQL_TINYINTInteger
SQL_BITBoolean

要找出哪些数据类型将返回表中的列使用该函数 describe_table/[2,3]

3.4批处理

为了减少网络流量,可能需要对SQL查询进行分组。另一个好处是数据源有时可以优化一批SQL查询的执行。

显式批处理下面描述的过程将导致从sql_query/2,3返回多个结果。而使用参数化查询时,只会从param_query/2,3返回一个结果。

显式批次

批处理的最基本形式是由分号分隔的SQL查询创建的,例如:

"SELECT * FROM FOO; SELECT * FROM BAR" or "INSERT INTO FOO VALUES(1,'bar' SELECT * FROM FOO"

程序

不同的数据库还可能支持创建包含多个SQL查询的过程。例如,下面的SQLSERVER特定语句创建了一个过程,该过程返回一个结果集,其中包含有关在部门工作的员工的信息,以及列出该部门客户的结果集。

CREATE PROCEDURE DepartmentInfo (@DepartmentID INT) AS SELECT * FROM Employee WHERE department = @DepartmentID SELECT * FROM Customers WHERE department = @DepartmentID

参数化查询

为了有效地执行一批类似的查询,可以使用参数化查询。这意味着您在您的SQL查询字符串中将标记通常包含带有问号值的位置,然后为每个参数提供值列表。例如,您可以使用它EMPLOYEE在执行一条SQL语句时将多行插入表中,例如代码请参见"Using the Erlang API"“入门”一章中的部分。