Skip to content

适用虚谷数据库版本

v12.9



适用虚谷数据库版本

v12.9


快速入门

📄字数 3.7K
👁️阅读量 加载中...

此章节将使用最简单的代码展示如何使用 XGCI 向虚谷数据库插入和查询数据,以及展示如何通过 XGCI 操作数值类型、字符类型和结构体类型的字段以实现数值的插入和查询。

创表

使用 xgconsole 或其他管理工具连接虚谷数据库实例,在 SYSTEM 库中创建此章节所依赖的表。建表语句如下:

SQL
CREATE TABLE tab_test (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(20),
    created DATE
);

认识句柄

在此章节中将使用四个句柄,分别是:环境句柄、服务器句柄、会话句柄和语句句柄。它们所对应的类型常量为:

  • HT_ENV
  • HT_SERVER
  • HT_SESSION
  • HT_STATEMENT

创建句柄

句柄的创建依赖于其它已成功创建的句柄,依赖关系为:

  • HT_ENV 没有依赖的句柄
  • HT_SERVER 依赖于 HT_ENV
  • HT_SESSION 依赖于 HT_SERVER
  • HT_STATEMENT 依赖于 HT_SESSION

创建句柄所使用的接口原型为:

C
XGCIRETURN XG_API XGCIHandleAlloc(XGCIHANDLE parenthndp, XGCIHANDLE* hndlpp, HANDLE_TYPE type);

其中,第一个参数为被依赖的句柄,第二个参数为待创建的句柄,第三个参数为待创建的句柄类型。创建成功则返回 XGCI_SUCCESS。因此创建句柄的代码为:

C
#include "xgci.h"
int main()
{
    XGCIHANDLE henv;
    XGCIHANDLE hserver;
    XGCIHANDLE hsession;
    XGCIHANDLE hstmt;

    // 创建环境句柄
    XGCIHandleAlloc(NULL, &henv, HT_ENV);
    // 创建服务器句柄
    XGCIHandleAlloc(henv, &hserver, HT_SERVER);
    // 创建会话句柄
    XGCIHandleAlloc(hserver, &hsession, HT_SESSION);
    // 创建语句句柄
    XGCIHandleAlloc(hsession, &hstmt, HT_STATEMENT);
    return 0;
}

设置连接信息

服务器句柄用于存储数据库的连接信息,IP、端口和待连接的库名均保存其中,设置连接信息的接口原型为:

C
XGCIRETURN XG_API XGCIHandleAttrSet(XGCIHANDLE hndp, int32 Attribute, const void* ValuePtr, int32 BuffLen);

其中,第一个参数为被设置值的句柄,第二个参数为值的类别,第三个参数为值,第四个参数为值的长度。设值成功则返回 XGCI_SUCCESS。当值的类型为字符串时,第四个参数可传入 XGCI_NTS,XGCI_NTS 代表取字符串的长度。

C
unsigned short port = 5138;
XGCIHandleAttrSet(hserver, XGCI_ATTR_SRV_IP, "127.0.0.1", XGCI_NTS);
XGCIHandleAttrSet(hserver, XGCI_ATTR_SRV_PORT, &port, 0);
XGCIHandleAttrSet(hserver, XGCI_ATTR_SRV_DBNAME, "SYSTEM", XGCI_NTS);

连接数据库

连接虚谷数据库至少需要五个信息,分别为:数据库服务端的 IP、数据库服务端的端口、被连接的库名、用户名和密码。连接数据库的接口原型为:

C
XGCIRETURN XG_API XGCISessionBegin(XGCIHSESS sesshndp, char* puser, char* ppwd);

其中,第一个参数为会话句柄,第二个参数为用户名,第三个参数为密码。连接成功则返回 XGCI_SUCCESS,若连接失败可使用 XGCIErrors 获取错误码以及错误信息。

C
int ret = XGCISessionBegin(hsession, (char*)"SYSDBA", (char*)"SYSDBA");
if (ret != XGCI_SUCCESS) 
{
    char errCode[7] = { 0 };
    char errMsg[256] = { 0 };
    int rlen = 0;
    XGCIErrors(handle, errCode, errMsg, &rlen);
    printf("[%s] %s\n", errCode, errMsg);
}

执行 SQL 语句

当连接建立成功后,即可向数据库服务端发送待执行的 SQL 语句。所使用的接口原型为:

C
XGCIRETURN XG_API XGCIExecDirect(XGCIHSTMT hndlp, char* sql_str, int32 str_len);

其中,第一个参数为语句句柄,第二个参数为 SQL 语句,第三个参数为 SQL 语句的长度。执行成功则返回 XGCI_SUCCESS,若执行失败可使用 XGCIErrors 获取错误码以及错误信息。

若执行查询,则需将变量绑定至各个列,通过 fetch 将当前行的值写入绑定的变量中。代码为:

C
const char* sql = "SELECT id, name, created FROM tab_test";
ret = XGCIExecDirect(hstmt, (char*)sql, XGCI_NTS);
if (ret == XGCI_SUCCESS) {
    int id;
    char name[20];
    DATE_STRUCT date;
    int rc[3];
    int len[3];
    XGCIDefineByPos(hstmt, 1, &id, 4, XG_C_INTEGER, &rc[0], &len[0]);
    XGCIDefineByPos(hstmt, 2, name, 20, XG_C_CHAR, &rc[1], &len[1]);
    XGCIDefineByPos(hstmt, 3, &date, 20, XG_C_DATE, &rc[2], &len[2]);
    while ((ret = XGCIFetch(hstmt)) == XGCI_SUCCESS) {
        printf("%d, %s, %d-%d-%d\n", id, name, date.year, date.month, date.day);
    }
}

销毁句柄

每个句柄均存储相关的信息,因此句柄使用完毕后需将其销毁以释放内存,其接口原型为:

C
XGCIRETURN XG_API XGCIHandleFree(XGCIHANDLE hndp);

其中,参数为待销毁的句柄。

C
XGCIHandleFree(hstmt);
XGCISessionEnd(hsession);
XGCIHandleFree(hserver);
XGCIHandleFree(henv);

完整代码

C
// main.cpp
#include <stdio.h>
#include <string.h>
#include "xgci.h"

void printError(XGCIHANDLE handle)
{
    char errCode[7] = { 0 };
    char errMsg[256] = { 0 };
    int len = 0;
    XGCIErrors(handle, errCode, errMsg, &len);
    printf("[%s] %s\n", errCode, errMsg);
}

void insert(XGCIHANDLE hstmt)
{
    const char* sql = "INSERT INTO tab_test (name, created) VALUES('张三', '2000-01-01')";
    int ret = XGCIExecDirect(hstmt, (char*)sql, strlen(sql));
    if (ret == XGCI_SUCCESS)
        printf("insert successfully\n");
    else
        printError(hstmt);
    XGCIFreeStmt(hstmt, XG_RESET);
}

void query(XGCIHANDLE hstmt)
{
    const char* sql = "SELECT id, name, created FROM tab_test";
    int ret = XGCIExecDirect(hstmt, (char*)sql, XGCI_NTS);
    if (ret != XGCI_SUCCESS) {
        printError(hstmt);
    } else {
        int id;
        char name[20];
        DATE_STRUCT date;
        int rc[3];
        int len[3];
        XGCIDefineByPos(hstmt, 1, &id, 4, XG_C_INTEGER, &rc[0], &len[0]);
        XGCIDefineByPos(hstmt, 2, name, 20, XG_C_CHAR, &rc[1], &len[1]);
        XGCIDefineByPos(hstmt, 3, &date, 20, XG_C_DATE, &rc[2], &len[2]);
        while ((ret = XGCIFetch(hstmt)) == XGCI_SUCCESS) {
            printf("%d, %s, %d-%d-%d\n", id, name, date.year, date.month, date.day);
        }
    }
}

int main()
{
    XGCIHANDLE henv;
    XGCIHANDLE hserver;
    XGCIHANDLE hsession;
    XGCIHANDLE hstmt;

    unsigned short port = 5138;
    int ret;

    XGCIHandleAlloc(NULL, &henv, HT_ENV);
    XGCIHandleAlloc(henv, &hserver, HT_SERVER);
    XGCIHandleAttrSet(hserver, XGCI_ATTR_SRV_IP, "127.0.0.1", XGCI_NTS);
    XGCIHandleAttrSet(hserver, XGCI_ATTR_SRV_PORT, &port, 0);
    XGCIHandleAttrSet(hserver, XGCI_ATTR_SRV_DBNAME, "SYSTEM", XGCI_NTS);

    XGCIHandleAlloc(hserver, &hsession, HT_SESSION);
    XGCIHandleAlloc(hsession, &hstmt, HT_STATEMENT);

    ret = XGCISessionBegin(hsession, (char*)"SYSDBA", (char*)"SYSDBA");
    if (ret == XGCI_SUCCESS) {
        insert(hstmt);
        query(hstmt);
        XGCISessionEnd(hsession);
    } else {
        printError(hsession);
    }

    XGCIHandleFree(hstmt);
    XGCISessionEnd(hsession);
    XGCIHandleFree(hserver);
    XGCIHandleFree(henv);
    return ret;
}