类型:转载 责任编辑:asp 日期:2007/03/01
想要一段源代码
关于c/c++和数据库(比如access)的互连
用代码实现
不用控件或者组件
推荐阅读
很老的,不过原理一样:
visual c++ 中 的odbc 编 程
华 中 理 工 大 学 电 力 工 程 系--董 毅
---- 摘 要:odbc, 是 一 种 用 来 在 相 关 或 不 相 关 的 数 据 库 管 理 系 统 中 存 取 数 据 的 标 准 应 用 程 序 接 口。 本 文 给 出windows 95 环 境 下 用visual c++ 进 行odbc 编 程 的 具 体 方 法 及 技 巧。
---- 关 键 字:odbc,visual c++,windows 编 程。
一 . 概 述
---- odbc 是 一 种 使 用sql 的 程 序 设 计 接 口。 使 用odbc 让 应 用 程 序 的 编 写 者 避 免 了 与 数 据 源 相 联 的 复 杂 性。 这 项 技 术 目 前 已 经 得 到 了 大 多 数dbms 厂 商 们 的 广 泛 支 持。
---- microsoft developer studio 为 大 多 数 标 准 的 数 据 库 格 式 提 供 了32 位odbc 驱 动 器。 这 些 标 准 数 据 格 式 包 括 有:sql server、access、paradox、dbase、foxpro、excel、oracle 以 及microsoft text。 如 果 用 户 希 望 使 用 其 他 数 据 格 式, 用 户 需 要 相 应 的odbc 驱 动 器 及dbms。
---- 用 户 使 用 自 己 的dbms 数 据 库 管 理 功 能 生 成 新 的 数 据 库 模 式 后, 就 可 以 使 用odbc 来 登 录 数 据 源。 对 用 户 的 应 用 程 序 来 说, 只 要 安 装 有 驱 动 程 序, 就 能 注 册 很 多 不 同 的 数 据 库。 登 录 数 据 库 的 具 体 操 作 参 见 有 关odbc 的 联 机 帮 助。
二 .mfc 提 供 的odbc 数 据 库 类
---- visual c++ 的mfc 基 类 库 定 义 了 几 个 数 据 库 类。 在 利 用odbc 编 程 时, 经 常 要 使 用 到 cdatabase( 数 据 库 类),crecordset( 记 录 集 类) 和crecordview( 可 视 记 录 集 类)。 其 中:
---- cdatabase 类 对 象 提 供 了 对 数 据 源 的 连 接, 通 过 它 你 可 以 对 数 据 源 进 行 操 作。
---- crecordset 类 对 象 提 供 了 从 数 据 源 中 提 取 出 的 记 录 集。crecordset 对 象 通 常 用 于 两 种 形 式: 动 态 行 集 和 快 照 集。 动 态 行 集 能 保 持 与 其 他 用 户 所 做 的 更 改 保 持 同 步。 快 照 集 则 是 数 据 的 一 个 静 态 视 图。 每 一 种 形 式 在 记 录 集 被 打 开 时 都 提 供 一 组 记 录, 所 不 同 的 是, 当 你 在 一 个 动 态 行 集 里 滚 动 到 一 条 记 录 时, 由 其 他 用 户 或 是 你 应 用 程 序 中 的 其 他 记 录 集 对 该 记 录 所 做 的 更 改 会 相 应 地 显 示 出 来。
---- crecordview 类 对 象 能 以 控 制 的 形 式 显 示 数 据 库 记 录。 这 个 视 图 是 直 接 连 到 一 个crecordset 对 象 的 表 视 图。
三 . 应 用odbc 编 程
---- 应 用visual c++ 的appwizard 可 以 自 动 生 成 一 个odbc 应 用 程 序 框 架。 方 法 是: 打 开file 菜 单 的new 选 项, 选 取projects, 填 入 工 程 名, 选 择mfc appwizard (exe), 然 后 按appwizard 的 提 示 进 行 操 作。 当appwizard 询 问 是 否 包 含 数 据 库 支 持 时, 如 果 你 想 读 写 数 据 库, 那 么 选 定database view with file support; 而 如 果 你 想 访 问 数 据 库 的 信 息 而 不 想 回 写 所 做 的 改 变, 那 么 选 定database view without file support 选 项 就 比 较 合 适 了。 选 择 了 数 据 库 支 持 之 后database source 按 钮 会 激 活, 选 中 它 去 调 用data options 对 话 框。 在database options 对 话 框 中 会 显 示 已 向odbc 注 册 的 数 据 库 资 源, 选 定 你 所 要 操 作 的 数 据 库, 如:super_es, 单 击ok 后 会 出 现select database tables 对 话 框, 其 中 列 举 了 你 所 选 中 的 数 据 库 中 包 含 的 全 部 表, 选 择 你 希 望 操 作 的 表 后, 单 击ok。 在 选 定 了 数 据 库 和 数 据 表 之 后, 你 可 以 按 照 惯 例 继 续 进 行appwizard 操 作。
---- 特 别 需 要 指 出 的 是: 在 生 成 的 应 用 程 序 框 架view 类 中 包 含 一 个 指 向csuper_esset 对 象 的 指 针m_pset, 该 指 针 由appwizard 建 立, 目 的 是 在 视 表 单 和 记 录 集 之 间 建 立 联 系, 使 得 记 录 集 中 的 查 询 结 果 能 够 很 容 易 地 在 视 表 单 上 显 示 出 来。 有 关m_pset 的 详 细 用 法 可 以 参 见visual c++ online book。
---- 程 序 与 数 据 语 言 建 立 联 系, 使 用cdatebase::openex() 或cdatabase::open() 函 数 来 进 行 初 始 化。 数 据 库 对 象 必 须 在 你 使 用 它 构 造 一 个 记 录 集 对 象 之 前 被 初 始 化。
---- 下 面 举 例 说 明 在visual c++ 环 境 中odbc 的 编 程 技 巧:
---- 1 . 查 询 记 录
---- 查 询 记 录 使 用crecordset::open() 和crecordset::requery() 成 员 函 数。 在 使 用crecordset 类 对 象 之 前, 必 须 使 用crecordset::open() 函 数 来 获 得 有 效 的 记 录 集。 一 旦 已 经 使 用 过crecordset::open() 函 数, 再 次 查 询 时 就 可 以 应 用crecordset::requery() 函 数。 在 调 用crecordset::open() 函 数 时, 如 果 已 经 将 一 个 已 经 打 开 的cdatabase 对 象 指 针 传 给crecordset 类 对 象 的m_pdatabase 成 员 变 量, 则 使 用 该 数 据 库 对 象 建 立odbc 连 接; 否 则 如 果m_pdatabase 为 空 指 针, 就 新 建 一 个cdatabase 类 对 象 并 使 其 与 缺 省 的 数 据 源 相 连, 然 后 进 行crecordset 类 对 象 的 初 始 化。 缺 省 数 据 源 由getdefaultconnect() 函 数 获 得。 你 也 可 以 提 供 你 所 需 要 的sql 语 句, 并 以 它 来 调 用crecordset::open() 函 数, 例 如:
---- super_esset.open(afx_database_use_default,strsql);
---- 如 果 没 有 指 定 参 数, 程 序 则 使 用 缺 省 的sql 语 句, 即 对 在getdefaultsql() 函 数 中 指 定 的sql 语 句 进 行 操 作:
cstring csuper_esset::getdefaultsql()
{return _t("[basicdata],[mainsize]");}
---- 对 于getdefaultsql() 函 数 返 回 的 表 名, 对 应 的 缺 省 操 作 是select 语 句, 即:
---- select * from basicdata,mainsize
---- 查 询 过 程 中 也 可 以 利 用crecordset 的 成 员 变 量m_strfilter 和m_strsort 来 执 行 条 件 查 询 和 结 果 排 序。m_strfilter 为 过 滤 字 符 串, 存 放 着sql 语 句 中where 后 的 条 件 串;m_strsort 为 排 序 字 符 串, 存 放 着sql 语 句 中order by 后 的 字 符 串。 如:
super_esset.m_strfilter="type= 电 动 机";
super_esset.m_strsort="voltage";
super_esset.requery();
对 应 的sql 语 句 为:
select * from basicdata,mainsize
where type= 电 动 机
order by voltage
---- 除 了 直 接 赋 值 给m_strfilter 以 外, 还 可 以 使 用 参 数 化。 利 用 参 数 化 可 以 更 直 观, 更 方 便 地 完 成 条 件 查 询 任 务。 使 用 参 数 化 的 步 骤 如 下:
---- (1) . 声 明 参 变 量:
cstring p1;
float p2;
---- (2) . 在 构 造 函 数 中 初 始 化 参 变 量
p1=_t("");
p2=0.0f;
m_nparams=2;
---- (3) . 将 参 变 量 与 对 应 列 绑 定
pfx->setfieldtype(cfieldexchange::param)
rfx_text(pfx,_t("p1"),p1);
rfx_single(pfx,_t("p2"),p2);
---- 完 成 以 上 步 骤 之 后 就 可 以 利 用 参 变 量 进 行 条 件 查 询 了:
m_pset->m_strfilter="type=? and voltage=?";
m_pset->p1=" 电 动 机";
m_pset->p2=60.0;
m_pset->requery();
你可以建立一个console程序
然后包含
如下文件:
<sql32.h>
<windows.h>
#prgma comment(lib, "odbc32.lib")
就可以在c/c++中使用odbc api 来进行数据库的访问了,注意室api不是mfc的类
不用控件的话,只能用该数据库商提供的api,否则是没办法访问数据库的。
除非你用java的jdbc接口,就可以开发跨平台、跨数据库的应用。但是目前在c/c++方面并没有像java的jdbc这种统一api,所以你的想法是不现实的。
用odbc的话还能提供一定的跨数据库功能。
给你发个连接的示例程序:
#include <stdio.h>
/////////////////odbc//////////////////////
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <odbcss.h>
#define channel_len 2
#define telenumber_len 15
sqlhandle hdbconn;
sqlchar sqlstate[6];
sqlinteger nativeerror;
sqlchar errmsg[sql_max_message_length];
sqlhenv hodbcenv = sql_null_henv;
sqlhstmt hstmt1 = sql_null_hstmt;
sqlhstmt hstmt_fee = sql_null_hstmt;
sqlhdbc hdbc1 = sql_null_hdbc;
sqlinteger cbchannel,cbtelenumber,channel;
void main( )
{
char szdsn[] = "datasource"; //odbc数据源
char szuid[] = "sa"; //sql用户
char szauthstr[] = "123"; //口令
sqlreturn sr;
sr = sqlallochandle(sql_handle_env,sql_null_handle,&hodbcenv);//分配odbc环境
sr = sqlsetenvattr(hodbcenv,sql_attr_odbc_version,(sqlpointer) sql_ov_odbc3,sql_is_integer);
//分配odbc连接句柄
sr = sqlallochandle(sql_handle_dbc,hodbcenv,&hdbconn); //连接选项
sr = sqlsetconnectattr(hdbconn,sql_attr_login_timeout,(void*)5,0); //连接
sr = sqlconnect(hdbconn, (sqlchar *)szdsn, sql_nts,(sqlchar *)szuid,sql_nts,(sqlchar*)szauthstr,sql_nts);
sr = sqlallochandle(sql_handle_stmt, hdbconn, &hstmt_fee); // 定位
if(sr==sql_invalid_handle||sr== sql_error)
{
printf(" error 1!\n");
return(-2);
}
sr = sqlprepare(hstmt_fee,(uchar *)szselect, sql_nts); // 数据准备
if(sr==sql_error || sr== sql_invalid_handle)
{
printf(" error 2!\n");
sqlfreehandle(sql_handle_stmt, hstmt_fee);
return(-3);
}
sr = sqlexecute(hstmt_fee); // 执行
//if(sr!=sql_success || sr!= sql_success_with_info || sr!= sql_no_data)
if (sr != 0 )
{
printf(" error 4",sr);
sqlfreehandle(sql_handle_stmt, hstmt_fee);
return(-4);
}
else if (sr == sql_no_data)
{
printf("sr:%d",sr);
printf("sql_no_data:%d",sql_no_data);
sqlfreehandle(sql_handle_stmt, hstmt_fee);
return ( 0 );
}
sr = sqlbindcol(hstmt_fee, 1, sql_c_char, // 绑定
telenumber, telenumber_len, &cbtelenumber);
if(sr==sql_error||sr==sql_invalid_handle)
{
printf(" error 5!\n");
sqlfreehandle(sql_handle_stmt, hstmt_fee);
return(-5);
}
// 取数据
sr = sqlfetch(hstmt_fee);
if(sr== sql_error||sr==sql_invalid_handle)
{
printf(" error 6!\n");
sqlfreehandle(sql_handle_stmt, hstmt_fee);
return(-6);
}
sqlfreehandle(sql_handle_stmt, hstmt_fee);
}
}
没有写得很详细
使用api开发框架就是
先分配句柄,然后构造sql语句,如果是查询的话,要取出结果
oracle可以采用更方便的嵌入式开发,利用oracle开发工具pro c_c++预编译,然后利用c编译工具编译,ok。如果需要例子,可以给我发信。
另外我有windows下利用c语言访问sqlserver和sybase数据库的代码,需要发信给我。
xinzhang_wei@hotmail.com
回复:wshcdr(dd)
lijdking(exploit)
oracle的sdk好象是集成在oracle软件上的,如果你没有oracle软件,你可以去oracle网站上去下载;