概述
有了 DB2 Run-Time Client 的 ODBC 支持,使用 Cloudscape 或者 Derby 的客户机开发人员就不再局限于只能使用 Java™ 编程语言。用 ODBC 接口可以访问使用 C/C++、Perl 和 .NET 等其他编程语言的数据。本文将重点介绍如何使用 ODBC .NET Data Provider 和 DB2 Run-Time Client 访问 IBM Cloudscape Version 10.0 和 Apache Derby 数据库中的数据。
ADO.NET 是自 ADO/OLE DB 以来 Microsoft 最新的数据访问技术。它是 Microsoft .NET 平台的一组数据访问接口和库,其设计中包含 XML 集成、分离数据访问及更好的更新控制。
ADO.NET 对象模型由一组“Connected”和“Disconnected”对象组成,这些对象称为 .NET Data Provider 和 Data Set。.NET 数据提供者充当的是 .NET 应用程序与基本数据源之间的数据驱动程序。它直接建立数据库连接来执行数据库操作,如数据更新和结果集检索。
ODBC .NET Data Provider 是一个受管制的组件,它允许 .NET 应用程序通过 ODBC 驱动程序访问 ODBC 数据源。IBM ODBC Driver 与 DB2 Runtime Client 封装在一起,这是使 Cloudscape/Derby 支持 ADO.NET 所必需的。对于 .NET Framework Version 1.1,ODBC .NET Data Provider 是作为框架的一部分包含于其中的,其名称空间是 System.Data.Odbc。而对于 .NET Framework v1.0,ODBC .NET Data Provider 则是单独提供的,其名称空间是 Microsoft.Data.Odbc。
Data Set 服务器被用作 .NET 应用程序的脱机数据缓存。对于如何通过 ADO.NET 方法在内存缓存数据集合与基本数据源之间提交数据更改,这些应用程序拥有完全的更新控制权。
有关 ADO.NET 的更多信息,请参阅本文的 参考资料部分。
IBM Cloudscape 是 IBM Apache Derby 开源数据库的商业版本。
软件要求
要 Cloudscape 支持 ADO.NET,需要以下软件:
Apache Derby 或 IBM Cloudscape Version 10.0 或更高版本。
IBM DB2 客户机运行时以及 IBM ODBC Driver Version 8.2 或更高版本。
.NET Framework Data Providers 讨论了如何使用 .NET Framework 数据提供者连接到数据库、执行命令和检索结果。
System.Data.Odbc Namespace 描述了 .NET Framework Data Provider for ODBC 使用的名称空间。
DB2 JDBC Universal 驱动程序。
要下载这些产品,请参阅本文的 参考资料部分。
设置
要通过 ODBC .NET Data Provider 在 Cloudscape/Derby 中建立对 ADO.NET 的支持,必须先将 Cloudscape/Derby 数据库设置为 ODBC 数据源。
启动 Cloudscape/Derby Network Server: java org.apache.derby.drda.NetworkServerControl start
在上例中,默认主机是“localhost”,默认端口是“1527”。有关的详细信息,请参阅 IBM Cloudscape/Derby Server and Administration Guide。
使用 ij 连接到 Cloudscape/Derby Network Server 并创建数据库,例如: java org.apache.derby.tools.ij
ij> connect jdbc:derby:net://localhost:1527/SAMPLEDB;create=true:user=abc;password=abc;;
本例创建了名为“SAMPLEDB”的 Cloudscape/Derby 数据库。
有关连接数据库的详细信息,请参阅 IBM Cloudscape/Derby Tools and Utilities Guide。
要连接数据库,则需要为 Cloudscape/Derby 安装 IBM DB2 Universal JDBC 驱动程序。请参阅本文的 参考资料部分。
使用 DB2 的命令行,通过 DB2 Runtime Client 对 Cloudscape/Derby Network Server 和数据库进行编目。例如:
db2 catalog tcpip node CNS remote localhost server 1527
db2 catalog db SAMPLEDB at node CNS authentication server
使用 DB2 命令行对数据库连接进行验证: db2 connect to SAMPLEDB user abc using abc
创建 ODBC 数据源。ODBC 数据源名称(DSN)包含访问数据库的连接信息。可以通过 ODBC Data Source Administrator,用以下两种方法进行创建和配置 ODBC 数据源:
在运行 Microsoft Windows 2000 或者 Windows XP 的计算机上,通过下列路径创建 ODBC 数据源: Start->Settings->Control Panel->Administrative Tools->Data Sources->System DSN
选定 IBM ODBC Driver,并选定与 DSN 相关联的编目数据库。
使用 DB2 命令行创建 ODBC 数据源: db2 catalog system odbc data source SAMPLEDB
确定 SAMPLEDB 数据库的 ODBC 数据源已经创建: db2 list system odbc data sources
如果上面的步骤执行正确,那么结果中应该列出 SAMPLEDB 数据源名称和 IBM DB2 ODBC DRIVER 类型。
如果已经对节点或者数据库进行了编目,那么上面显示的命令将失败。如果遇到失败,则取消对节点或者数据库的编目,然后重新再试: db2 uncatalog node CNS
db2 uncatalog db SAMPLEDB
在 Windows 中,也可以用 ODBC Data Source 工具设置 SAMPLEDB,快速确定 ODBC 是否能连接到 Derby/Cloudscape Data Source。要在 Windows XP 中访问该工具,请转至 Start --> Control Panel --> Administrative Tools --> Data Sources (ODBC)。这将打开 ODBC Data Source Administrator。选择 System DSN 选项卡,如果对 SAMPLEDB Data Source 进行了正确编目,那么您将在列表中看到这个数据源。
高亮显示 Name 列中的 SAMPLEDB,然后单击左边的 Configure... 按钮。您将看到与下图相似的窗口。
图 1. 确认与 Derby 数据源的 ODBC 连接
使用在端口 1527 的 localhost 上运行的 Derby/Cloudscape Network Server,填充 User ID 和 Password 值,然后单击 Connect 按钮,测试到 Cloudscape 数据源 SAMPLEDB 的连接。将会出现一个弹出框,通知您连接是否成功。
成功执行上面的步骤之后,安装包含 ODBC .NET Data Provider 的 .NET Framework Version 1.1。如果使用 .NET Framework Version 1.0,那么必须单独下载 ODBC .NET Data Provider。
示例
下列示例代码段将说明如何使用 ODBC .NET Data Provider 访问 Cloudscape/Derby 数据库。后面的 下载部分提供了完整的 C# 示例。要编译完整的 C# 示例代码,需要安装 .NET Framework v1.1 SDK 并使用 C# 编译器 csc.exe。例如,下列代码将编译一个名为 Sample1.cs 的 C# 源文件,并创建一个名为Sample1.exe 的控制台应用程序: csc /target:exe Sample1.cs
清单 1 将展示如何使用“abc”作为用户 ID 和口令,建立与名为“SAMPLEDB”的数据库的连接。
清单1:建立连接
String connString = "DSN=SAMPLEDB;UID=abc;PWD=abc;";
// where datasource name is SAMPLEDB
OdbcConnection conn = new OdbcConnection(connString);
conn.Open();
清单 2 将显示如何启动、执行和提交事务。
清单 2:执行语句和使用事务
// conn is an OdbcConnection instance
OdbcCommand cmd = conn.CreateCommand();
OdbcTransaction trans = conn.BeginTransaction(); // start a transaction
cmd.Transaction = trans;
cmd.CommandText = "UPDATE staff " + " SET salary = (SELECT MIN(salary) " +
" FROM staff " + " WHERE id >= 310) " + " WHERE id = 310";
cmd.ExecuteNonQuery(); // execute the statement
trans.Commit(); // commit the transaction
清单 3 将显示如何调用存储过程。
清单 3:执行存储过程
// conn is an OdbcConnection instance
OdbcCommand cmd = conn.CreateCommand();
cmd.CommandText = "CALL IN_PARAM(?)";
// Register input parameter for the OdbcCommand
cmd.Parameters.Add(new OdbcParameter("@p1", OdbcType.Int));
cmd.Parameters[0].Value = 100;
// Call the stored procedure
cmd.ExecuteNonQuery();
清单 4 读取查询结果。
清单 4:读取 ResultSet
// conn is an OdbcConnection instance
OdbcCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT sid, name FROM staff WHERE sid > 100";
OdbcDataReader reader = cmd.ExecuteReader();
Int32 sid = 0;
String name = "";
// Output the results of the query
while(reader.Read()) {
sid = reader.GetInt32(0); // first column
name = reader.GetString(1); // second column
Console.WriteLine(" " + sid + " " + name);
}
reader.Close();
清单 5 将显示如何与 Cloudscape/Derby 数据库建立连接、创建表、向表中插入一些行,然后从表中提取并显示这些行。
清单 5:C# 示例
// Note: This C# example uses .NET Framework v1.1
// It connects to a Cloudscape/Derby database named SAMPLEDB.
// It creates a table called staff, inserts 3 rows, then fetches
// and displays the result set on the console.
using System;
using System.Data;
using System.Data.Odbc;
namespace IBM.Cloudscape.Samples
{
class Sample1
{
[STAThread]
static void Main(string[] args)
{
//String connString = @"Driver={IBM DB2 ODBC
//DRIVER};DBALIAS=SAMPLEDB;UID=abc;PWD=abc";
String connString = @"DSN=SAMPLEDB;UID=abc;PWD=abc"; // using DSN
OdbcConnection conn = null;
OdbcCommand cmd = null;
Console.WriteLine("Connecting to SAMPLEDB");
try
{
conn = new OdbcConnection(connString);
// open database connection
conn.Open();
Console.WriteLine("Connected to SAMPLEDB");
// creates a table named staff
cmd = new OdbcCommand("CREATE TABLE staff
(sid INT PRIMARY KEY NOT NULL, name VARCHAR(30)
NOT NULL, salary INT NOT NULL)", conn);
cmd.ExecuteNonQuery();
Console.WriteLine("Table staff created");
// insert data to table staff
cmd.CommandText = "INSERT INTO staff VALUES (300, John, 35000)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO staff VALUES (310, Mary, 55000)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO staff VALUES (320, Tom, 35000)";
cmd.ExecuteNonQuery();
Console.WriteLine("3 rows inserted");
// Fetch data from table staff
cmd = new OdbcCommand("SELECT * FROM staff", conn);
OdbcDataReader rdr = cmd.ExecuteReader();
Console.WriteLine("Fetching rows from staff");
while (rdr.Read())
{
Console.Write(rdr.GetInt32(0));
Console.Write(" " + rdr.GetString(1) + " ");
Console.WriteLine(rdr.GetInt32(2));
}
rdr.Close();
}
catch (OdbcException ex)
{
int cnt = ex.Errors.Count;
for (int i=0; i < cnt; i++)
{
Console.WriteLine("Error #" + i + "\n" +
"Message: " + ex.Errors[i].Message + "\n" +
"Native: " + ex.Errors[i].NativeError.ToString() + "\n" +
"SQL: " + ex.Errors[i].SQLState + "\n");
}
}
finally
{
if (conn != null)
conn.Close();
Console.WriteLine("Sample1 ended");
}
}
}
}