3.数据库 | 3. Databases
3 数据库
3.1数据库
如果您需要访问关系数据库,例如sqlserver
,mysql
,postgres
,oracle
,cybase
等使用Erlang的ODBC接口的应用二郎是去了解它的好方法。
Erlang ODBC应用程序应该适用于任何具有ODBC驱动程序的关系数据库。但目前它只是经常测试sqlserver
和postgres
。
3.2数据库独立性
Erlang ODBC接口与数据库主体无关,因此使用该接口的erlang程序可以在不改变数据库的情况下运行。但是,当使用SQL时,编写数据库相关程序是可能的。尽管SQL是一种ANSI标准,意味着与数据库无关,但不同的数据库拥有对SQL定义自己数据类型的专有扩展。如果您遵守ANSI数据类型,您将最大限度地减少问题。但不幸的是,并不能保证所有的数据库实际上都等价地处理ANSI数据类型。例如,安装Oracle Enterprise release 8.0.5.0.0 for unix
will将接受使用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 >= 16 | String |
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 >= 16 | String |
SQL_INTEGER | Integer |
SQL_SMALLINT | Integer |
SQL_FLOAT | Float |
SQL_REAL | Float |
SQL_DOUBLE | Float |
SQL_VARCHAR(size) | String | Binary (configurable) |
SQL_WVARCHAR(size) | Unicode binary encoded as UTF16 little endian. |
ODBC数据类型 | Erlang数据类型 |
---|---|
SQL_TYPE_DATE | String |
SQL_TYPE_TIME | String |
SQL_TYPE_TIMESTAMP | {{YY, MM, DD}, {HH, MM, SS}} |
SQL_LONGVARCHAR | String | Binary (configurable) |
SQL_WLONGVARCHAR(size) | Unicode binary encoded as UTF16 little endian. |
SQL_BINARY | String | Binary (configurable) |
SQL_VARBINARY | String | Binary (configurable) |
SQL_LONGVARBINARY | String | Binary (configurable) |
SQL_TINYINT | Integer |
SQL_BIT | Boolean |
注
要找出哪些数据类型将返回表中的列使用该函数 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"
“入门”一章中的部分。