神通数据库ACI编程基础

ACI编程基础

ACI 用户编程的基本流程如下:

  1. 初始化神通 ACI 接口的运行环境
  2. 分配环境句柄、语句句柄、服务器句柄、会话句柄等数据结构
  3. 建立与神通数据库的连接以及创建用户会话
  4. 通过 SQL 语句与神通数据库服务器交互,然后对获取的数据进行处理
  5. 结束用户会话,断开 ACI 接口与神通数据库的连接
  6. 释放在程序中所分配的各类句柄和资源

使用的函数

  1. 准备 SQL 语句调用函数ACIStmtPrepare
  2. 在 SQL 语句中绑定需要输入到 SQL 语句中的变量
    对于 DML 语句来说,由于它带有输入变量,我们可以通过调用一个或者多个函数CIBindByPos /ACIBindByPos2 / ACIBindByName / ACIBindByName2 等把输入变量的地址绑定在 DML 语句中的占位符中;
  3. 执行 SQL 语句
    调用ACIStmtExecute 函数。对于 DDL 语句到这一步就完成了一个语句的执行
  4. 描述 SQL 中的输出的数据
    如果有必要的话,我们可以调用函数ACIParamGet 与ACIAttrGet 来获取我们所读取的记录的字段个数、字段的数据类型以及字段数据定义的最大长度。
  5. 定义输出变量
    对于 DQL(Data Query Language) 语句,即 SELECT 的查询语句,需要定义一定数量的变量用来接受所选择列的数据。我们可以调用ACIDefineByPos 函数等来完成这个任务。也就建立 SQL 语句所返回的数据与应用程序中变量的关系。
  6. 获取数据
    我们可以调用函数ACIStmtFetch 来把用 SELECT 选中的记录的数据赋予应用程序中的变量。过程以及过程中调用到的函数如所示。
    在这里插入图片描述

编程例子

/*
本例中的 SQL 语句为 SELECT 语句,假设后台数据库中存在表名为 mt_t 表
建表语句
create table mt_t(id number(10),col1 number(10));
insert into mt_t values(10,100);
insert into mt_t values(11,1000);
*/
#include <aci.h>
/* 句柄分配 */
ACIEnv *m_penv = NULL; /* 环境句柄 */
ACIError *m_perr = NULL; /* 错误句柄 */
ACIServer *m_psrv = NULL; /* 服务器句柄 */
ACISvcCtx *m_psvc = NULL; /* 服务上下文句柄 */
ACISession *m_pses = NULL; /* 会话句柄 */
ACIStmt *m_pstmt = NULL; /* 语句句柄 */
ACIBind *m_bnd = NULL; /* 绑定句柄 */
ACIDefine *m_def = NULL; /* 定义句柄 */
typedef struct
{
int sID;
int sCol1;
} Record;
int main()
{
/*----------变量定义-------------*/
sword r = ACI_SUCCESS;
char *m_dblink = "127.0.0.1:2003/OSRDB";
char *m_dbuser = "SYSDBA";
char *m_dbpwd = "szoscar55";
char ssql[] = "select * from mt_t where id=:id";
int id = 10;
Record rec = { 1,2 };
/*----------分配并初始化各类应用句柄-------------*/
r = ACIInitialize(ACI_DEFAULT, NULL, NULL, NULL, NULL);
r = ACIEnvInit(&m_penv, ACI_DEFAULT, 0, 0);
r = ACIHandleAlloc(m_penv, (void**)&m_perr, ACI_HTYPE_ERROR, 0, 0);
r = ACIHandleAlloc(m_penv, (void**)&m_pstmt, ACI_HTYPE_STMT, 0, 0);
/*----------连接数据库-------------*/
r = ACILogon(m_penv, m_perr, &m_psvc, (const OraText *)m_dbuser, strlen(m_dbuser), (const OraText *)m_dbpwd, strlen(m_dbpwd), (const OraText *)m_dblink, strlen(m_dblink));
/*----------准备 SQL 语句-------------*/
r = ACIStmtPrepare(m_pstmt, m_perr, (OraText*)ssql, strlen(ssql), ACI_HTYPE_ERROR, ACI_DEFAULT);
/*----------按位置进行绑定-------------*/
r = ACIBindByPos(m_pstmt, &m_bnd, m_perr, 1, (void *)&id, sizeof(id), SQLT_INT, (void*)0, (ub2*)0, (ub2*)0, 0, 0, ACI_DEFAULT);
/*----------按位置进行定义-------------*/
r = ACIDefineByPos(m_pstmt, &m_def, m_perr, 1, (void*)&rec.sID, sizeof(rec.sID), SQLT_INT, (void*)0, 0, 0, ACI_DEFAULT);
r = ACIDefineByPos(m_pstmt, &m_def, m_perr, 2, (void *)&rec.sCol1, sizeof(rec.sCol1), SQLT_INT, (void*)0, 0, 0, ACI_DEFAULT);
/*----------执行 SQL 语句-------------*/
r = ACIStmtExecute(m_psvc, m_pstmt, m_perr, 0, 0, 0, 0, ACI_DEFAULT);
/*----------结果获取-------------*/
while (((r = ACIStmtFetch(m_pstmt, m_perr, 0, ACI_FETCH_NEXT, ACI_DEFAULT)) != ACI_NO_DATA))
{
printf("%d, %d \n", rec.sID, rec.sCol1);
}
}

Text类型读取


#include <iostream>
#include <oscar/aci.h>
#include <string.h>

ACIEnv *m_penv = NULL;
ACIError *m_perr = NULL;
ACIServer *m_psrv = NULL;
ACISvcCtx *m_psvc = NULL;
ACISession *m_pses = NULL;
ACIStmt *m_pstmt = NULL;
ACIBind *m_pbnd = NULL;
ACIDefine *m_pdef = NULL;
int main()
{
sword r = ACI_SUCCESS;
ub1 errbuf[64] = { 0 }; //获取错误信息的缓冲区
ub1 sqlstate[64] = { 0 }; //ACIErroGet() 的第三个参数变量
sb4 ercodep = 0;
ub2 *rlp = NULL, rcodep = NULL;
char dsql[] = "drop table tt";
char createSql[] = "create table tt(Profession text)";//创建表
char insql[] = "insert into tt values(:1)";//插入数据
char ssql[] = "select * from tt";//查询数据
char *m_dblink = (char *)"127.0.0.1:2003/OSRDB";
char *m_dbuser = (char *) "SYSDBA";
char *m_dbpwd = (char *)"szoscar55";
//初始化环境句柄
r = ACIInitialize(ACI_DEFAULT, NULL, NULL, NULL, NULL);
r = ACIEnvInit(&m_penv, ACI_DEFAULT, 0, 0);
//分配并初始化各类句柄
ACIHandleAlloc(m_penv, (void**)&m_perr, ACI_HTYPE_ERROR, 0, 0);
ACIHandleAlloc(m_penv, (void**)&m_psrv, ACI_HTYPE_SERVER, 0, 0);
ACIHandleAlloc(m_penv, (void**)&m_psvc, ACI_HTYPE_SVCCTX, 0, 0);
ACIHandleAlloc(m_penv, (void**)&m_pses, ACI_HTYPE_SESSION, 0, 0);
ACIHandleAlloc(m_penv, (void**)&m_pstmt, ACI_HTYPE_STMT, 0, 0);
//连接数据库
r = ACILogon(m_penv, m_perr, &m_psvc, (const OraText*)m_dbuser, strlen(m_dbuser),
(const OraText*)m_dbpwd, strlen(m_dbpwd), (const OraText*)m_dblink, strlen(m_dblink));
r = ACIStmtPrepare(m_pstmt, m_perr, (OraText*)dsql, strlen(dsql), ACI_HTYPE_ERROR, ACI_DEFAULT);
r = ACIStmtExecute(m_psvc, m_pstmt, m_perr, 1, 0, 0, 0, ACI_DEFAULT);
//创建数据库
r = ACIStmtPrepare(m_pstmt, m_perr, (OraText*)createSql, strlen(createSql), ACI_HTYPE_ERROR, ACI_DEFAULT);
r = ACIStmtExecute(m_psvc, m_pstmt, m_perr, 1, 0, 0, 0, ACI_DEFAULT);
//插入数据
r = ACIStmtPrepare(m_pstmt, m_perr, (OraText*)insql, strlen(insql), ACI_HTYPE_ERROR, ACI_DEFAULT);
char profession[5][16] = { "小品演员","歌手","相声演员","演员、歌手","演员、歌手" };
int indp3[] = { 0,0,0,0,0 };
ub2 alenp3[] = { 16,16,16,16,16 };
r = ACIBindByPos(m_pstmt, &m_pbnd, m_perr, 1, (void*)profession[0], sizeof(profession[0]), SQLT_STR, indp3, alenp3, 0, 5, 0, ACI_DEFAULT);
r = ACIBindArrayOfStruct(m_pbnd, m_perr, sizeof(profession[0]), sizeof(int), sizeof(ub2), 0);
r = ACIStmtExecute(m_psvc, m_pstmt, m_perr, 5/* 总共有 6 行 */, 0, 0, 0, ACI_DEFAULT);
ACITransCommit(m_psvc, m_perr, ACI_DEFAULT);
//查询
char profession3[6][16] = { 0 };
r = ACIStmtPrepare(m_pstmt, m_perr, (OraText*)ssql, strlen(ssql), ACI_HTYPE_ERROR, ACI_DEFAULT);
r = ACIDefineByPos(m_pstmt, &m_pdef, m_perr, 1, (void*)profession3[0], sizeof(profession3[0]), SQLT_STR,
(void*)0, (ub2*)rlp, (ub2*)rcodep, ACI_DEFAULT);
r = ACIDefineArrayOfStruct(m_pdef, m_perr, sizeof(profession3[0]), 0, 0, 0);
r = ACIStmtExecute(m_psvc, m_pstmt, m_perr, 0, 0, 0, 0, ACI_DEFAULT);
while ((r = ACIStmtFetch(m_pstmt, m_perr, 5, ACI_FETCH_NEXT, ACI_DEFAULT)) != ACI_NO_DATA)
{
int i;
for (i = 0; i < 5; i++)
printf("%s\n", profession3[i]);
}
return 0;
}



函数使用

ACIStmtFetch()
作用:从查询中获取行。
sword ACIStmtFetch ( ACIStmt *stmtp,ACIError *errhp,ub4 nrows,ub2 orientation,ub4 mode );
• stmthp (in)
指向返回的语句句柄的指针。
• errhp (IN)
指向用于诊断的错误句柄的指针。
• nrows (IN)
从当前位置获取的行数,如果在 nrows 参数设置为 0 的情况下调用ACIStmtFetch ,则将关闭游标
• orientation (IN)
唯一可接受的值为 ACI_FETCH_NEXT,这也是默认值。
• mode (IN)
支持 ACI_DEFAULT.

方向设置为 ACI_FETCH_RELATIVE 的 fetchOffset 等效于所有以下各项:
ACI_FETCH_CURRENT 的 fetchOffset 值等于 0
ACI_FETCH_NEXT 的值 fetchOffset 等于 1
ACI_FETCH_PRIOR 的值 fetchOffset 等于-1

ACIStmtPrepare()
作用:
准备要执行的 SQL 或 PL / SQL 语句。不推荐使用此功能。
sword ACIStmtPrepare ( ACIStmt *stmtp,ACIError *errhp,const OraText *stmt,ub4 tmt_len,ub4 language,ub4 mode );

• stmtp (IN)
与要执行的语句关联的语句句柄。默认情况下,它在派生其的环境句柄中包含编码设置。只能在 UTF-16 环
境中以 UTF-16 编码准备语句。
• errhp (IN)
当发生错误时,可以将错误句柄传递给ACIErrorGet 以获取诊断信息。
• stmt (IN)
要执行的 SQL 或 PL / SQL 语句。必须是以 NULL 结尾的字符串。也就是说,根据编码,结束字符为 NULL
字节数。该语句必须使用先前对ACIEnvNlsCreate 的调用的 charset 参数指定的编码。
始终将参数强制转换为(text * )。在 UTF-16 中准备好语句后,绑定和定义缓冲区的字符集默认为 UTF-16。
• stmt_len (IN)
语句的长度(以字符或字节数为单位),取决于编码。不能为零。
• language (IN)


aci库的位置在/opt/Shentong/drivers/aci目录下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值