这里感谢我的那位超酷的朋友,感谢他愿意在我困惑的时候为我伸出援手。
我这次是用的kingbase和mysql,记得当时出现了蛮多问题的,不过现在我已经不记得出了什么问题了…
学会配置ODBC数据源。熟悉使用ODBC来进行数据库应用程序的设计,熟悉通过ODBC接口访问异构数据库并对异构数据库进行操作。
实验平台:KingbaseES数据库管理系统,KingbaseES ODBC Driver。
通过C语言编写访问数据库的应用程序。编程工具自选。
在KingbaseES数据库管理系统上,通过KingbaseES ODBC Driver,使用ODBC编写应用程序来对异构数据库进行各种数据操作。
配置两个不同的数据源,编写程序连接两个不同RDBMS的数据源,对异构数据库进行操作。例如,将KingbaseES数据库的某个表中的数据备份到SQL Server数据库的表中。
要认真填写实验报告,并且提交源程序,保证可正确编译和运行。
什么是ODBC
ODBC(OpenDatabaseConnectivity,开放数据库互连)是微软公司开放服务结构(WOSA,WindowsOpenServicesArchitecture)中有关数据库的一个组成部分,这一技术为访问不同种类的 SQL数据库提供了通用接口。
ODBC是基于结构查询语言(SQL)的,并以此作为访问数据的标准。该接口提供了互操作性,即一个应用程序可以通过一组公用代码访问不同的DBMS。
配置ODBC数据源的方式
配置数据源共有两种方法:
方法一:运行数据源管理工具来进行配置。
方法二:使用Driver Manager 提供的ConfigDsn函数来增加、修改或删除数据源。这种方法特别适用于在应用程序中创建的临时使用的数据源。
给出配置两个不同的数据源的过程。提交应用程序源代码,并标识必要的注释,尽可能清楚明白地说明程序的功能,实现的方法,关键数据结构、变量、函数的定义。
1.MySQL数据源配置
1-1.安装MySQL的ODBC驱动
1-2.数据源配置
打开【控制面板】,进入【系统和安全】,选择【Windows 工具】,打开【ODBC 数据源(64位)】
在用户DSN中添加【MySQL ODBC 8.0 ANSI Driver】
(这里选择Unicode更好一点,这样就可以正常显示中文了)
输入对应的信息,然后选择我们的test数据库,点击【test】
成功的话会显示这个界面
2.KingBase数据源配置
2-1.安装KingBase的ODBC驱动
2-2.数据源配置
打开【控制面板】,进入【系统和安全】,选择【Windows 工具】,打开【ODBC 数据源(64位)】
在用户DSN中添加【KingbaseES 8.6 ODBC Driver ANSI】
(这里选择Unicode更好一点,这样就可以正常显示中文了)
输入对应的信息,然后选择我们的test数据库,点击【测试】
成功的话会显示这个界面
3.实验代码
#include
#include
#include
#include
#include
#include
#include
#define SNO_LEN 30
#define NAME_LEN 50
#define DEPART_LEN 100
#define SSEX_LEN 5
int main() {
/*Step 1 定义句柄和变量*/
/*以king开头的表示是连接KingbaseES的变量*/
/*以server开头的表示是连接MySQL的变量*/
SQLHENV kinghenv, serverhenv; /*环境句柄*/
SQLHDBC kinghdbc, serverhdbc; /*连接句柄*/
SQLHSTMT kinghstmt, serverhstmt; /*语句句柄*/
SQLRETURN ret;
SQLCHAR sName[NAME_LEN] = { 0 }, sDepart[DEPART_LEN] = { 0 },
sSex[SSEX_LEN] = { 0 }, sSno[SNO_LEN] = { 0 };
SQLINTEGER sAge = 0;
SQLLEN cbAge = 0, cbSno = SQL_NTS, cbSex = SQL_NTS,
cbName = SQL_NTS, cbDepart = SQL_NTS;
/*Step 2 初始化环境*/
ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &kinghenv);
ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &serverhenv);
ret = SQLSetEnvAttr(kinghenv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3,
0);
ret = SQLSetEnvAttr(serverhenv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3,
0);
/*Step 3 建立连接*/
ret = SQLAllocHandle(SQL_HANDLE_DBC, kinghenv, &kinghdbc);
ret = SQLAllocHandle(SQL_HANDLE_DBC, serverhenv, &serverhdbc);
ret = SQLConnect(kinghdbc, (SQLWCHAR*)_T("KingBaseES"), SQL_NTS,
(SQLWCHAR*)_T("system"), SQL_NTS, (SQLWCHAR*)_T("123"), SQL_NTS); //数据源 用户名
密码
if (!SQL_SUCCEEDED(ret)) /*连接失败时返回错误值*/
{
printf("连接bu成功!");
return -1;
}
else printf("连接成功!");
ret = SQLConnect(serverhdbc, (SQLWCHAR*)_T("db_lab7"), SQL_NTS,
(SQLWCHAR*)_T("root"), SQL_NTS, (SQLWCHAR*)_T("zhk200176"), SQL_NTS);
if (!SQL_SUCCEEDED(ret)) /*连接失败时返回错误值*/
{
printf("连接bu成功!");
return -1;
}
else printf("连接成功!");
/*STEP 4 初始化语句句柄*/
ret = SQLAllocHandle(SQL_HANDLE_STMT, kinghdbc, &kinghstmt);
ret = SQLSetStmtAttr(kinghstmt, SQL_ATTR_ROW_BIND_TYPE,
(SQLPOINTER)SQL_BIND_BY_COLUMN, SQL_IS_INTEGER);
ret = SQLAllocHandle(SQL_HANDLE_STMT, serverhdbc, &serverhstmt);
/*STEP 5 两种方式执行语句*/
/*预编译带有参数的语句*/
SQLWCHAR sql[] = _T("INSERT INTO student(sno,sname,ssex,sage,sdept)
VALUES(?,?,?,?,?)");
ret = SQLPrepare(serverhstmt, sql, SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
ret = SQLBindParameter(serverhstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR, SNO_LEN, 0, sSno, 0, &cbSno);
ret = SQLBindParameter(serverhstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR, NAME_LEN, 0, sName, 0, &cbName);
ret = SQLBindParameter(serverhstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR, SSEX_LEN, 0, sSex, 0, &cbSex);
ret = SQLBindParameter(serverhstmt, 4, SQL_PARAM_INPUT, SQL_C_LONG,
SQL_INTEGER, 0, 0, &sAge, 0, &cbAge);
ret = SQLBindParameter(serverhstmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR, DEPART_LEN, 0, sDepart, 0, &cbDepart);
}
/*执行 SQL 语句*/
ret = SQLExecDirect(kinghstmt, (SQLWCHAR*)_T("SELECT * FROM student"),
SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
ret = SQLBindCol(kinghstmt, 1, SQL_C_CHAR, sSno, SNO_LEN, &cbSno);
ret = SQLBindCol(kinghstmt, 2, SQL_C_CHAR, sName, NAME_LEN, &cbName);
ret = SQLBindCol(kinghstmt, 3, SQL_C_CHAR, sSex, SSEX_LEN, &cbSex);
ret = SQLBindCol(kinghstmt, 4, SQL_C_LONG, &sAge, 0, &cbAge);
ret = SQLBindCol(kinghstmt, 5, SQL_C_CHAR, sDepart, DEPART_LEN,
&cbDepart);
}
/*Step 6 处理结果集并执行预编译后的语句*/
while ((ret = SQLFetch(kinghstmt)) != SQL_NO_DATA_FOUND)
{
if (ret == SQL_ERROR) printf("Fetch error\n");
else ret = SQLExecute(serverhstmt);
}
/*Step 7 中止处理*/
SQLFreeHandle(SQL_HANDLE_STMT, kinghstmt);
SQLDisconnect(kinghdbc);
SQLFreeHandle(SQL_HANDLE_DBC, kinghdbc);
SQLFreeHandle(SQL_HANDLE_ENV, kinghenv);
SQLFreeHandle(SQL_HANDLE_STMT, serverhstmt);
SQLDisconnect(serverhdbc);
SQLFreeHandle(SQL_HANDLE_DBC, serverhdbc);
SQLFreeHandle(SQL_HANDLE_ENV, serverhenv);
return 0;
}