#C驱动使用示例

YashanDB C驱动客户端程序cexample.c:

以下示例包含C驱动常用功能:

1、连接数据库。

2、断开数据库。

3、单行绑定导入数据。

4、单行取数据。

5、批量绑定导入数据。

6、批量取数据。

7、单行绑定LOB导入数据。

8、单行取LOB数据。

9、批量绑定导入LOB数据(使用连续内存导入)。

10、批量取LOB数据(使用连续内存获取)。

11、单行获取cursor数据。

12、LOB接口读写LOB数据(使用LOB2接口)。

#include <string.h>
#include "yacli.h"


#define YAC_CALL(proc)                           \
    do {                                         \
        if ((YacResult)(proc) != YAC_SUCCESS) {  \
            return YAC_ERROR;                    \
        }                                        \
    } while (0)

void printError()
{
    YacInt32   code;
    YacChar    msg[1000];
    YacTextPos pos;

    yacGetDiagRec(&code, msg, 1000, NULL, NULL, 0, &pos);
    if (pos.line != 0) {
        printf("[%d:%d]", pos.line, pos.column);
    }
    printf("YAC-%05d %s\n", code, msg);
}

typedef struct {
    YacHandle env;
    YacHandle conn;
    YacHandle stmt;
} YacTestEnv;

YacTestEnv gTestEnv = { 0 };

// C驱动常用操作:

// 1、连接数据库
YacResult testConnect()
{
    //更改为实际数据库服务器的IP和端口
    const YacChar* gSrvStr = "127.0.0.1:1688";
    const YacChar* user = "sys";
    const YacChar* pwd = "password";

    YAC_CALL(yacAllocHandle(YAC_HANDLE_ENV, NULL, &gTestEnv.env));
    YAC_CALL(yacAllocHandle(YAC_HANDLE_DBC, gTestEnv.env, &gTestEnv.conn));
    YAC_CALL(yacConnect(gTestEnv.conn, gSrvStr, YAC_NULL_TERM_STR, user, YAC_NULL_TERM_STR, pwd, YAC_NULL_TERM_STR));
    YAC_CALL(yacAllocHandle(YAC_HANDLE_STMT, gTestEnv.conn, &gTestEnv.stmt));

    return YAC_SUCCESS;
}

// 2、断开数据库
YacResult testDisConnect()
{
    YAC_CALL(yacFreeHandle(YAC_HANDLE_STMT, gTestEnv.stmt));
    yacDisconnect(gTestEnv.conn);
    YAC_CALL(yacFreeHandle(YAC_HANDLE_DBC, gTestEnv.conn));
    YAC_CALL(yacFreeHandle(YAC_HANDLE_ENV, gTestEnv.env));

    return YAC_SUCCESS;
}

// 3、单行绑定导入数据
YacResult testSingleBind()
{
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "drop table if exists test_yacli", YAC_NULL_TERM_STR));
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "create table test_yacli(col1 int, col2 varchar(200))", YAC_NULL_TERM_STR));

    YAC_CALL(yacPrepare(gTestEnv.stmt, "insert into test_yacli values(?, ?)", YAC_NULL_TERM_STR));

    YacInt32 inputInt;
    YacChar  inputVarchar[200];
    YacInt32 indicator;
    YAC_CALL(yacBindParameter(gTestEnv.stmt, 1, YAC_PARAM_INPUT, YAC_SQLT_INTEGER, &inputInt, sizeof(YacInt32), sizeof(YacInt32), NULL));
    YAC_CALL(yacBindParameter(gTestEnv.stmt, 2, YAC_PARAM_INPUT, YAC_SQLT_VARCHAR2, inputVarchar, 200, 200, &indicator));

    /* insert data
    99,  '0123456789'
    100, '9876543210'
    */
    inputInt = 99;
    memcpy(inputVarchar, "0123456789", 10);
    indicator = 10;
    YAC_CALL(yacExecute(gTestEnv.stmt));

    inputInt = 100;
    memcpy(inputVarchar, "98765", 10);
    indicator = 5;
    YAC_CALL(yacExecute(gTestEnv.stmt));

    YAC_CALL(yacCommit(gTestEnv.conn));

    return YAC_SUCCESS;
}

// 4、单行取数据
YacResult testSingleFetch()
{
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "select * from test_yacli", YAC_NULL_TERM_STR));

    YacInt32 outputInt;
    YacChar  outputVarchar[200];
    YacInt32 indicator;
    YAC_CALL(yacBindColumn(gTestEnv.stmt, 0, YAC_SQLT_INTEGER, &outputInt, sizeof(YacInt32), NULL));
    YAC_CALL(yacBindColumn(gTestEnv.stmt, 1, YAC_SQLT_VARCHAR2, outputVarchar, 200, &indicator));

    /* fetch data
    99,  '0123456789'
    100, '9876543210'
    */
    YacUint32 fetchedRows;
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    if (fetchedRows != 1 || outputInt != 99 || memcmp(outputVarchar, "0123456789", indicator) != 0 || indicator != 10)
    {
        return YAC_ERROR;
    }

    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    if (fetchedRows != 1 || outputInt != 100 || memcmp(outputVarchar, "9876543210", indicator) != 0 || indicator != 5)
    {
        return YAC_ERROR;
    }

    return YAC_SUCCESS;
}

// 5、批量绑定导入数据
YacResult testBatchBind()
{
    YacUint32 paramSet = 10;
    YAC_CALL(yacSetStmtAttr(gTestEnv.stmt, YAC_ATTR_PARAMSET_SIZE, &paramSet, sizeof(YacUint32)));
    // 设置批量绑定行数为10

    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "drop table if exists test_yacli", YAC_NULL_TERM_STR));
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "create table test_yacli(col1 int, col2 varchar(200))", YAC_NULL_TERM_STR));

    YAC_CALL(yacPrepare(gTestEnv.stmt, "insert into test_yacli values(?, ?)", YAC_NULL_TERM_STR));

    YacInt32 inputInt[10];
    YacChar  inputVarchar[10][200];
    YacInt32 indicator[10];
    YAC_CALL(yacBindParameter(gTestEnv.stmt, 1, YAC_PARAM_INPUT, YAC_SQLT_INTEGER, &inputInt, sizeof(YacInt32), sizeof(YacInt32), NULL));
    YAC_CALL(yacBindParameter(gTestEnv.stmt, 2, YAC_PARAM_INPUT, YAC_SQLT_VARCHAR2, (YacPointer)inputVarchar, 200, 200, indicator));

    /*insert data
    batch insert 1
    1,   '0123456789'
    2,   '0123456789'
    3,   '0123456789'
    4,   '0123456789'
    5,   '0123456789'
    6,   '0123456789'
    7,   '0123456789'
    8,   '0123456789'
    9,   '0123456789'
    10,  '0123456789'
    batch insert 2
    11,  '9876543210'
    12,  '9876543210'
    13,  '9876543210'
    14,  '9876543210'
    15,  '9876543210'
    16,  '9876543210'
    17,  '9876543210'
    18,  '9876543210'
    19,  '9876543210'
    20,  '9876543210'
    */
    for (YacInt32 i = 0; i < 10; i++)
    {
        inputInt[i] = i + 1;
        memcpy(inputVarchar[i], "0123456789", 10);
        indicator[i] = 10;
    }
    YAC_CALL(yacExecute(gTestEnv.stmt));

    for (YacInt32 i = 0; i < 10; i++)
    {
        inputInt[i] = i + 11;
        memcpy(inputVarchar[i], "9876543210", 10);
        indicator[i] = 10;
    }
    YAC_CALL(yacExecute(gTestEnv.stmt));

    YAC_CALL(yacCommit(gTestEnv.conn));

    paramSet = 1;
    YAC_CALL(yacSetStmtAttr(gTestEnv.stmt, YAC_ATTR_PARAMSET_SIZE, &paramSet, sizeof(YacUint32)));
    // 设置批量绑定行数为1

    return YAC_SUCCESS;
}

// 6、批量取数据
YacResult testBatchFetch()
{
    YacUint32 rowSet = 10;
    YAC_CALL(yacSetStmtAttr(gTestEnv.stmt, YAC_ATTR_ROWSET_SIZE, &rowSet, sizeof(YacUint32)));
    // 设置批量取数据绑定行数为10

    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "select * from test_yacli", YAC_NULL_TERM_STR));

    YacInt32 outputInt[10];
    YacChar  outputVarchar[10][200];
    YacInt32 indicator[10];
    YAC_CALL(yacBindColumn(gTestEnv.stmt, 0, YAC_SQLT_INTEGER, &outputInt, sizeof(YacInt32), NULL));
    YAC_CALL(yacBindColumn(gTestEnv.stmt, 1, YAC_SQLT_VARCHAR2, (YacPointer)outputVarchar, 200, indicator));

    /*fetch data
    batch fetch 1
    1,   '0123456789'
    2,   '0123456789'
    3,   '0123456789'
    4,   '0123456789'
    5,   '0123456789'
    6,   '0123456789'
    7,   '0123456789'
    8,   '0123456789'
    9,   '0123456789'
    10,  '0123456789'
    batch fetch 2
    11,  '9876543210'
    12,  '9876543210'
    13,  '9876543210'
    14,  '9876543210'
    15,  '9876543210'
    16,  '9876543210'
    17,  '9876543210'
    18,  '9876543210'
    19,  '9876543210'
    20,  '9876543210'
    */
    YacUint32 fetchedRows;
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    if (fetchedRows != 10)
    {
        return YAC_ERROR;
    }
    for (YacInt32 i = 0; i < 10; i++)
    {
        if (outputInt[i] != i + 1 || memcmp(outputVarchar[i], "0123456789", indicator[i]) != 0 || indicator[i] != 10)
        {
            return YAC_ERROR;
        }
    }

    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    if (fetchedRows != 10)
    {
        return YAC_ERROR;
    }
    for (YacInt32 i = 0; i < 10; i++)
    {
        if (outputInt[i] != i + 11 || memcmp(outputVarchar[i], "9876543210", indicator[i]) != 0 || indicator[i] != 10)
        {
            return YAC_ERROR;
        }
    }

    rowSet = 1;
    YAC_CALL(yacSetStmtAttr(gTestEnv.stmt, YAC_ATTR_ROWSET_SIZE, &rowSet, sizeof(YacUint32)));
    // 设置批量取数据绑定行数为1

    return YAC_SUCCESS;
}

// 7、单行绑定LOB导入数据
YacResult testSingleBindLob()
{
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "drop table if exists test_yacli", YAC_NULL_TERM_STR));
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "create table test_yacli(col1 clob, col2 blob)", YAC_NULL_TERM_STR));

    YAC_CALL(yacPrepare(gTestEnv.stmt, "insert into test_yacli values(?, ?)", YAC_NULL_TERM_STR));

    YacLobLocator* lobLocator1;
    YacLobLocator* lobLocator2;

    YAC_CALL(yacBindParameter(gTestEnv.stmt, 1, YAC_PARAM_INPUT, YAC_SQLT_CLOB, &lobLocator1, 0, 0, NULL));
    YAC_CALL(yacBindParameter(gTestEnv.stmt, 2, YAC_PARAM_INPUT, YAC_SQLT_BLOB, &lobLocator2, 0, 0, NULL));

    /* insert lob data
    '01234567899876543210',  'aaaaaaaaaabbbbbbbbbb'
    '98765432100123456789',  'bbbbbbbbbbaaaaaaaaaa'
    */

    // first row insert
    YAC_CALL(yacLobDescAlloc(gTestEnv.conn, YAC_TYPE_CLOB, (YacVoid**)&lobLocator1));
    YAC_CALL(yacLobDescAlloc(gTestEnv.conn, YAC_TYPE_BLOB, (YacVoid**)&lobLocator2));
    YAC_CALL(yacLobCreateTemporary(gTestEnv.conn, lobLocator1));
    YAC_CALL(yacLobCreateTemporary(gTestEnv.conn, lobLocator2));
    YacChar buf1[100] = "01234567899876543210";
    YAC_CALL(yacLobWrite(gTestEnv.conn, lobLocator1, NULL, (YacUint8*)buf1, 10));
    YAC_CALL(yacLobWrite(gTestEnv.conn, lobLocator1, NULL, (YacUint8*)(buf1 + 10), 10));
    YacChar buf2[100] = "aaaaaaaaaabbbbbbbbbb";
    YAC_CALL(yacLobWrite(gTestEnv.conn, lobLocator2, NULL, (YacUint8*)buf2, 10));
    YAC_CALL(yacLobWrite(gTestEnv.conn, lobLocator2, NULL, (YacUint8*)(buf2 + 10), 10));
    YAC_CALL(yacExecute(gTestEnv.stmt));
    YAC_CALL(yacLobFreeTemporary(gTestEnv.conn, lobLocator1));
    YAC_CALL(yacLobFreeTemporary(gTestEnv.conn, lobLocator2));
    YAC_CALL(yacLobDescFree(lobLocator1, YAC_TYPE_CLOB));
    YAC_CALL(yacLobDescFree(lobLocator2, YAC_TYPE_BLOB));

    // second row insert
    YAC_CALL(yacLobDescAlloc(gTestEnv.conn, YAC_TYPE_CLOB, (YacVoid**)&lobLocator1));
    YAC_CALL(yacLobDescAlloc(gTestEnv.conn, YAC_TYPE_BLOB, (YacVoid**)&lobLocator2));
    YAC_CALL(yacLobCreateTemporary(gTestEnv.conn, lobLocator1));
    YAC_CALL(yacLobCreateTemporary(gTestEnv.conn, lobLocator2));
    YacChar buf3[100] = "98765432100123456789";
    YAC_CALL(yacLobWrite(gTestEnv.conn, lobLocator1, NULL, (YacUint8*)buf3, 10));
    YAC_CALL(yacLobWrite(gTestEnv.conn, lobLocator1, NULL, (YacUint8*)(buf3 + 10), 10));
    YacChar buf4[100] = "bbbbbbbbbbaaaaaaaaaa";
    YAC_CALL(yacLobWrite(gTestEnv.conn, lobLocator2, NULL, (YacUint8*)buf4, 10));
    YAC_CALL(yacLobWrite(gTestEnv.conn, lobLocator2, NULL, (YacUint8*)(buf4 + 10), 10));
    YAC_CALL(yacExecute(gTestEnv.stmt));
    YAC_CALL(yacLobFreeTemporary(gTestEnv.conn, lobLocator1));
    YAC_CALL(yacLobFreeTemporary(gTestEnv.conn, lobLocator2));
    YAC_CALL(yacLobDescFree(lobLocator1, YAC_TYPE_CLOB));
    YAC_CALL(yacLobDescFree(lobLocator2, YAC_TYPE_BLOB));

    YAC_CALL(yacCommit(gTestEnv.conn));

    return YAC_SUCCESS;
}

// 8、单行取LOB数据
YacResult testSingleFetchLob()
{
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "select * from test_yacli", YAC_NULL_TERM_STR));

    YacLobLocator* lobLocator1;
    YacLobLocator* lobLocator2;

    YacInt32 indicator[2];
    YAC_CALL(yacBindColumn(gTestEnv.stmt, 0, YAC_SQLT_CLOB, &lobLocator1, 0, &indicator[0]));
    YAC_CALL(yacBindColumn(gTestEnv.stmt, 1, YAC_SQLT_BLOB, &lobLocator2, 0, &indicator[1]));

    YAC_CALL(yacLobDescAlloc(gTestEnv.conn, YAC_TYPE_CLOB, (YacVoid**)&lobLocator1));
    YAC_CALL(yacLobDescAlloc(gTestEnv.conn, YAC_TYPE_BLOB, (YacVoid**)&lobLocator2));

    /* fetch lob data
    '01234567899876543210',  'aaaaaaaaaabbbbbbbbbb'
    '98765432100123456789',  'bbbbbbbbbbaaaaaaaaaa'
    */

    YacUint32 fetchedRows;
    YacChar buf1[100];
    YacUint64 bytes1 = 100;
    YacChar buf2[100];
    YacUint64 bytes2 = 100;

    // first row fetch
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    if (indicator[0] == YAC_NULL_DATA || indicator[1] == YAC_NULL_DATA) {
        return YAC_ERROR;
    }
    YAC_CALL(yacLobRead(gTestEnv.conn, lobLocator1, &bytes1, (YacUint8*)buf1, 0));
    YAC_CALL(yacLobRead(gTestEnv.conn, lobLocator2, &bytes2, (YacUint8*)buf2, 0));
    if (fetchedRows != 1 || memcmp(buf1, "01234567899876543210", bytes1) != 0 || memcmp(buf2, "aaaaaaaaaabbbbbbbbbb", bytes2) != 0)
    {
        return YAC_ERROR;
    }

    // second row fetch
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    YAC_CALL(yacLobRead(gTestEnv.conn, lobLocator1, &bytes1, (YacUint8*)buf1, 0));
    YAC_CALL(yacLobRead(gTestEnv.conn, lobLocator2, &bytes2, (YacUint8*)buf2, 0));
    if (fetchedRows != 1 || memcmp(buf1, "98765432100123456789", bytes1) != 0 || memcmp(buf2, "bbbbbbbbbbaaaaaaaaaa", bytes2) != 0)
    {
        return YAC_ERROR;
    }

    YAC_CALL(yacLobDescFree(lobLocator1, YAC_TYPE_CLOB));
    YAC_CALL(yacLobDescFree(lobLocator2, YAC_TYPE_BLOB));

    return YAC_SUCCESS;
}

// 9、批量绑定导入LOB数据(使用连续内存导入)
#define PARAM_SET_SIZE 10
#define MAX_LOB_SIZE (80 << 20) // 80M
YacResult testMultiBindLobByContinuousMemory()
{
    YacUint32 paramSet = PARAM_SET_SIZE;
    YAC_CALL(yacSetStmtAttr(gTestEnv.stmt, YAC_ATTR_PARAMSET_SIZE, &paramSet, sizeof(YacUint32)));
    // 设置批量绑定行数为10

    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "drop table if exists test_yacli", YAC_NULL_TERM_STR));
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "create table test_yacli(col1 clob, col2 blob)", YAC_NULL_TERM_STR));

    YAC_CALL(yacPrepare(gTestEnv.stmt, "insert into test_yacli values(?, ?)", YAC_NULL_TERM_STR));

    YacChar* bufClob = (YacChar*)malloc(MAX_LOB_SIZE * PARAM_SET_SIZE);
    if (bufClob == NULL) {
        return YAC_ERROR;
    }

    YacChar* bufBlob = (YacChar*)malloc(MAX_LOB_SIZE * PARAM_SET_SIZE);
    if (bufBlob == NULL) {
        return YAC_ERROR;
    }

    YacInt32 indicator1[PARAM_SET_SIZE] = { 0 };
    YacInt32 indicator2[PARAM_SET_SIZE] = { 0 };

    YacChar* buf1 = bufClob + MAX_LOB_SIZE * 1;
    YacChar* buf2 = bufClob + MAX_LOB_SIZE * 2;
    YacChar* buf3 = bufClob + MAX_LOB_SIZE * 3;
    YacChar* buf4 = bufClob + MAX_LOB_SIZE * 4;

    for (YacUint32 i = 0; i < PARAM_SET_SIZE; i++) {
        memset(bufClob + MAX_LOB_SIZE * i, 'a' + i, i + 1);
        indicator1[i] = i + 1;
    }

    for (YacUint32 i = 0; i < PARAM_SET_SIZE; i++) {
        memset(bufBlob + MAX_LOB_SIZE * i, '0' + i, i + 1);
        indicator2[i] = i + 1;
    }

    YAC_CALL(yacBindParameter(gTestEnv.stmt, 1, YAC_PARAM_INPUT, YAC_SQLT_VARCHAR2, bufClob, MAX_LOB_SIZE, MAX_LOB_SIZE, indicator1));
    YAC_CALL(yacBindParameter(gTestEnv.stmt, 2, YAC_PARAM_INPUT, YAC_SQLT_BINARY2, bufBlob, MAX_LOB_SIZE, MAX_LOB_SIZE, indicator2));

    /* 每批插入的数据
    'a',           30
    'bb',          3131
    'ccc',         323232
    'dddd',        33333333
    'eeeee',       3434343434
    'ffffff',      353535353535
    'ggggggg',     36363636363636
    'hhhhhhhh',    3737373737373737
    'iiiiiiiii',   383838383838383838
    'jjjjjjjjjj',  39393939393939393939
    */

    //执行几次就插入几批,此处插入40行
    YAC_CALL(yacExecute(gTestEnv.stmt));
    //yacExecute中间可以修改数据
    YAC_CALL(yacExecute(gTestEnv.stmt));
    YAC_CALL(yacExecute(gTestEnv.stmt));
    YAC_CALL(yacExecute(gTestEnv.stmt));

    YAC_CALL(yacCommit(gTestEnv.conn));

    free(bufClob);
    free(bufBlob);

    return YAC_SUCCESS;
}

// 10、批量取LOB数据(使用连续内存获取)
#define ROW_SET_SIZE 10
YacResult testMultiFetchLobByContinuousMemory()
{
    YacUint32 rowSet = ROW_SET_SIZE;
    YAC_CALL(yacSetStmtAttr(gTestEnv.stmt, YAC_ATTR_ROWSET_SIZE, &rowSet, sizeof(YacUint32)));
    // 设置批量取数据绑定行数为10

    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "select * from test_yacli", YAC_NULL_TERM_STR));

    YacChar* bufClob = (YacChar*)malloc(MAX_LOB_SIZE * PARAM_SET_SIZE);
    if (bufClob == NULL) {
        return YAC_ERROR;
    }

    YacChar* bufBlob = (YacChar*)malloc(MAX_LOB_SIZE * PARAM_SET_SIZE);
    if (bufBlob == NULL) {
        return YAC_ERROR;
    }

    YacInt32 indicator1[PARAM_SET_SIZE] = { 0 };
    YacInt32 indicator2[PARAM_SET_SIZE] = { 0 };

    YAC_CALL(yacBindColumn(gTestEnv.stmt, 0, YAC_SQLT_VARCHAR2, bufClob, MAX_LOB_SIZE, indicator1));
    YAC_CALL(yacBindColumn(gTestEnv.stmt, 1, YAC_SQLT_BINARY2, bufBlob, MAX_LOB_SIZE, indicator2));

    /* 每批获取到的数据
    'a',           30
    'bb',          3131
    'ccc',         323232
    'dddd',        33333333
    'eeeee',       3434343434
    'ffffff',      353535353535
    'ggggggg',     36363636363636
    'hhhhhhhh',    3737373737373737
    'iiiiiiiii',   383838383838383838
    'jjjjjjjjjj',  39393939393939393939
    */

    YacUint32 fetchedRows;

    //fetch几次就获取几批,此处获取40行,fetchedRows返回当前批获取的行数
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));

    free(bufClob);
    free(bufBlob);

    return YAC_SUCCESS;
}

// 11、单行获取cursor数据。
YacResult testSelectCursor()
{
    YacHandle stmt = NULL;
    YAC_CALL(yacAllocHandle(YAC_HANDLE_STMT, gTestEnv.conn, &stmt));

    const YacChar* sql1 = "drop table if exists t2_cursor";
    const YacChar* sql2 = "create table t2_cursor (col1 int,col2 varchar(10))";
    const YacChar* sql3 = "insert into t2_cursor values (1,'9999')";
    const YacChar* sql4 = "insert into t2_cursor values (10,'99999')";
    YacInt32       sqlLen1 = (YacInt32)strlen(sql1);
    YacInt32       sqlLen2 = (YacInt32)strlen(sql2);
    YacInt32       sqlLen3 = (YacInt32)strlen(sql3);
    YacInt32       sqlLen4 = (YacInt32)strlen(sql4);

    YAC_CALL(yacDirectExecute(stmt, sql1, sqlLen1));
    YAC_CALL(yacDirectExecute(stmt, sql2, sqlLen2));
    YAC_CALL(yacDirectExecute(stmt, sql3, sqlLen3));
    YAC_CALL(yacDirectExecute(stmt, sql4, sqlLen4));

    YacChar* functionSql = (YacChar*)
        "create or replace function selectcursor(c1 in int) "
        "return sys_refcursor as "
        "c2 sys_refcursor; "
        "begin "
        "  open c2 for "
        "    select * from t2_cursor where col1 = c1; "
        "  return c2; "
        "end;";

    YacHandle cursor1;
    YacInt32  proLen = (YacInt32)strlen(functionSql);
    YAC_CALL(yacDirectExecute(stmt, functionSql, proLen));

    YacChar* selectSql = "select selectcursor(1) from dual";
    YAC_CALL(yacDirectExecute(stmt, selectSql, (YacInt32)strlen(selectSql)));
    YAC_CALL(yacBindColumn(stmt, 0, YAC_SQLT_CURSOR, (YacPointer)&cursor1, sizeof(YacHandle), NULL));

    YacUint32 cursorRows = 0;
    YAC_CALL(yacFetch(stmt, &cursorRows));

    //corsor的数据
    YacInt32 value1;
    YacInt32 value2;
    YAC_CALL(yacBindColumn(cursor1, 0, YAC_SQLT_INTEGER, &value1, sizeof(YacInt32), NULL));
    YAC_CALL(yacBindColumn(cursor1, 1, YAC_SQLT_INTEGER, &value2, sizeof(YacInt32), NULL));


    YacUint32 rows = 0;
    YAC_CALL(yacFetch(cursor1, &rows));

    YAC_CALL(yacFreeHandle(YAC_HANDLE_STMT, stmt));
    YAC_CALL(yacFreeHandle(YAC_HANDLE_STMT, cursor1));

    return YAC_SUCCESS;
}

// 12、LOB接口读写LOB数据(使用LOB2接口)
YacResult testOperatingLob()
{
    YacUint32 rowSet = 1;
    YAC_CALL(yacSetStmtAttr(gTestEnv.stmt, YAC_ATTR_ROWSET_SIZE, &rowSet, sizeof(YacUint32)));

    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "drop table if exists test_yacli_lob", YAC_NULL_TERM_STR));
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "create table test_yacli_lob(col1 clob, col2 blob)", YAC_NULL_TERM_STR));
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "insert into test_yacli_lob values('aaaaaaaaaabbbbbbbbbb', '4142434445')", YAC_NULL_TERM_STR));
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "insert into test_yacli_lob values('bbbbbbbbbbaaaaaaaaaa', '4243444546')", YAC_NULL_TERM_STR));
    YAC_CALL(yacCommit(gTestEnv.conn));
    YAC_CALL(yacDirectExecute(gTestEnv.stmt, "select * from test_yacli_lob for update", YAC_NULL_TERM_STR));


    YacLobLocator* lobLocator1 = NULL;
    YacLobLocator* lobLocator2 = NULL;
    YAC_CALL(yacLobDescAlloc2(gTestEnv.conn, &lobLocator1));
    YAC_CALL(yacLobDescAlloc2(gTestEnv.conn, &lobLocator2));

    YacInt32 indicator[2];
    YAC_CALL(yacBindColumn(gTestEnv.stmt, 0, YAC_SQLT_CLOB, &lobLocator1, -1, &indicator[0]));
    YAC_CALL(yacBindColumn(gTestEnv.stmt, 1, YAC_SQLT_BLOB, &lobLocator2, -1, &indicator[1]));


    /* fetch lob data
    'aaaaaaaaaabbbbbbbbbb',  '4142434445'
    'bbbbbbbbbbaaaaaaaaaa',  '4243444546'
    */

    YacUint32 fetchedRows = 0;
    YacChar buf1[100];
    YacUint64 byteSize1 = 0;
    YacUint64 charSize1 = 100;
    YacChar buf2[100];
    YacUint64 byteSize2 = 100;
    YacUint64 charSize2 = 0;
    YacUint64 offset = 1;
    YacUint64 bytes1 = 100;
    YacUint64 bytes2 = 100;

    // first row fetch
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    if (indicator[0] == YAC_NULL_DATA || indicator[1] == YAC_NULL_DATA) {
        return YAC_ERROR;
    }
    YAC_CALL(yacLobRead2(gTestEnv.conn, lobLocator1, &byteSize1, &charSize1, offset, (YacUint8*)buf1, 100));
    YAC_CALL(yacLobRead2(gTestEnv.conn, lobLocator2, &byteSize2, &charSize2, offset, (YacUint8*)buf2, 100));
    if (fetchedRows != 1 || memcmp(buf1, "aaaaaaaaaabbbbbbbbbb", byteSize1) != 0 || memcmp(buf2, "ABCDE", byteSize2) != 0)
    {
        return YAC_ERROR;
    }

    // second row fetch
    YAC_CALL(yacFetch(gTestEnv.stmt, &fetchedRows));
    YAC_CALL(yacLobRead2(gTestEnv.conn, lobLocator1, &byteSize1, &charSize1, offset, (YacUint8*)buf1, 100));
    YAC_CALL(yacLobRead2(gTestEnv.conn, lobLocator2, &byteSize2, &charSize2, offset, (YacUint8*)buf2, 100));
    if (fetchedRows != 1 || memcmp(buf1, "bbbbbbbbbbaaaaaaaaaa", byteSize1) != 0 || memcmp(buf2, "BCDEF", byteSize2) != 0)
    {
        return YAC_ERROR;
    }

    charSize1 = 10;
    YAC_CALL(yacLobWrite2(gTestEnv.conn, lobLocator1, &byteSize1, &charSize1, offset, (YacUint8*)buf1, 100));
    YAC_CALL(yacLobWriteAppend(gTestEnv.conn, lobLocator1, &byteSize1, &charSize1, (YacUint8*)buf1, 100));

    YacUint64 newlen = 5;
    YAC_CALL(yacLobTrim(gTestEnv.conn, lobLocator1, &newlen));

    YAC_CALL(yacRollback(gTestEnv.conn));

    YAC_CALL(yacLobDescFree2(lobLocator1));
    YAC_CALL(yacLobDescFree2(lobLocator2));
    return YAC_SUCCESS;
}

YacResult cexample()
{
    YAC_CALL(testConnect());
    YAC_CALL(testSingleBind());
    YAC_CALL(testSingleFetch());
    YAC_CALL(testBatchBind());
    YAC_CALL(testBatchFetch());
    YAC_CALL(testSingleBindLob());
    YAC_CALL(testSingleFetchLob());
    YAC_CALL(testMultiBindLobByContinuousMemory());
    YAC_CALL(testMultiFetchLobByContinuousMemory());
    YAC_CALL(testSelectCursor());
    YAC_CALL(testOperatingLob());
    YAC_CALL(testDisConnect());

    return YAC_SUCCESS;
}

int main()
{
    if (cexample() == YAC_SUCCESS) {
        printf("cexample succeed!\n");
    } else {
        printError();
        printf("cexample failed!\n");
    }
    return 0;
}
Copied!
下载文档
复制链接