【YashanDB知识库】YashanDB-OCI-快速上手

本文内容来自YashanDB官网,具体内容请见https://www.yashandb.com/newsinfo/7488285.html?templateId=1718516

背景

OCI 是Oracle调用接口(Oracle Call Interface 简称OCI) 提供了一组对Oracle数据库进行存取的接口子例程(函数),通过在第三方设计语言(如C语言)中进行调用可达到存取ORACLE数据库的目的。

崖山数据库基于Oracle的OCI接口,开发了强兼容的接口,应用可以做比较少的改动,平滑地迁移到崖山数据库。

主要优点

1、Oracle数据库服务器特性中的即时可用性

2、企业级的性能和可伸缩性

3、强健的安全模型

4、在所有运行Oracle的平台上的可移植性。

本文将介绍cmake 方式编译崖山数据库,帮助读者快速上手崖山数据库的OCI接口,并在使用OCI解决实际工作遇到的问题。

环境准备

1、配置yashandb的C驱动 和 OCI 文件

2、准备Oracle的OCI软件包,需要下载两个:

其一是instantclient-basic-linux.x64-21.14.0.0.0dbru.zip,

其二是instantclient-sdk-linux.x64-21.14.0.0.0dbru.zip

3、机器提前安装GDB和CMAKE工具

如何编译yashandb的OCI代码?

接下来,以官网OCI示例代码为例,快速上手编译Yashandb的OCI代码

准备编译前命令

编辑 CMakeList.txt,它是CMAKE工程编译的声明命令文件

点击查看代码
[yashan103@localhost oci_dir]$ cat CMakeLists.txt

cmake_minimum_required(VERSION 2.8.12)

# CMAKE的工程名

project(YAS_OCI_TEST)

set(CMAKE_CXX_STANDARD 11)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(BUILD_USE_64BITS on)

set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE)

set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE)

#设置OCI接口的源代码路径

SET(LIBHELLO_SRC

./bb.c

)

#查找库文件

find_library(YAS_OCI_LIBRARY NAMES yas_oci PATHS /home/yashan103/oci_lib/yashandb-oci-23.2.1.100-4-gecc0e02-linux-x86_64)

#确认库文件是否找到

if(NOT YAS_OCI_LIBRARY)

   message(FATAL_ERROR "Could not find libyas_oci.so")

endif()

# 添加OCI.h的头文件

include_directories(/home/yashan103/instantclient_21_12/sdk/include)

##执行编译操作

add_executable(YAS_OCI_TEST ${LIBHELLO_SRC})


##添加OCI的yashandb依赖文件

target_link_libraries(YAS_OCI_TEST ${YAS_OCI_LIBRARY})

[yashan103@localhost oci_dir]$

[yashan103@localhost oci_dir]$

[yashan103@localhost oci_dir]$ cat CMakeLists.txt

cmake_minimum_required(VERSION 2.8.12)

# CMAKE的工程名

project(YAS_OCI_TEST)

set(CMAKE_CXX_STANDARD 11)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(BUILD_USE_64BITS on)

set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE)

set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE)

#设置OCI接口的源代码路径

SET(LIBHELLO_SRC

./bb.c

)

#查找库文件

find_library(YAS_OCI_LIBRARY NAMES yas_oci PATHS /home/yashan103/oci_lib/yashandb-oci-23.2.1.100-4-gecc0e02-linux-x86_64)

#确认库文件是否找到

if(NOT YAS_OCI_LIBRARY)

   message(FATAL_ERROR "Could not find libyas_oci.so")

endif()

# 添加OCI.h的头文件

include_directories(/home/yashan103/instantclient_21_12/sdk/include)

##执行编译操作

add_executable(YAS_OCI_TEST ${LIBHELLO_SRC})

##添加OCI的yashandb依赖文件

target_link_libraries(YAS_OCI_TEST ${YAS_OCI_LIBRARY})
准备Oracle的依赖文件 点击查看代码
[yashan103@localhost instantclient_21_12]$ ll

total 272500

-rwxr-xr-x. 1 yashan103 yashan103 42192 Dec 21 2023 adrci

-rw-r--r--. 1 yashan103 yashan103 5780 Dec 21 2023 BASIC_LICENSE

-rw-r--r--. 1 yashan103 yashan103 1634 Dec 21 2023 BASIC_README

drwxrwxr-x. 2 yashan103 yashan103 55 Apr 1 10:46 bin

-rwxr-xr-x. 1 yashan103 yashan103 59544 Dec 21 2023 genezi

drwxrwxr-x. 2 yashan103 yashan103 6 Aug 5 21:38 include

drwxrwxr-x. 2 yashan103 yashan103 6 Aug 5 21:38 lib

lrwxrwxrwx. 1 yashan103 yashan103 21 Jul 23 11:22 libclntshcore.so -> libclntshcore.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 21 Jul 23 11:22 libclntshcore.so.12.1 -> libclntshcore.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 21 Jul 23 11:22 libclntshcore.so.18.1 -> libclntshcore.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 21 Jul 23 11:22 libclntshcore.so.19.1 -> libclntshcore.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 21 Jul 23 11:22 libclntshcore.so.20.1 -> libclntshcore.so.21.1

-rwxr-xr-x. 1 yashan103 yashan103 8108592 Dec 21 2023 libclntshcore.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 17 Jul 23 11:22 libclntsh.so -> libclntsh.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 17 Jul 23 11:22 libclntsh.so.10.1 -> libclntsh.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 17 Jul 23 11:22 libclntsh.so.11.1 -> libclntsh.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 17 Jul 23 11:22 libclntsh.so.12.1 -> libclntsh.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 17 Jul 23 11:22 libclntsh.so.18.1 -> libclntsh.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 17 Jul 23 11:22 libclntsh.so.19.1 -> libclntsh.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 17 Jul 23 11:22 libclntsh.so.20.1 -> libclntsh.so.21.1

-rwxr-xr-x. 1 yashan103 yashan103 84191392 Dec 21 2023 libclntsh.so.21.1

-rw-r--r--. 1 yashan103 yashan103 3412144 Apr 1 10:46 libcrypto.so.1.1

lrwxrwxrwx. 1 yashan103 yashan103 14 Apr 1 10:46 libcsvexp.so -> libcsvexp.so.0

lrwxrwxrwx. 1 yashan103 yashan103 20 Apr 1 10:46 libcsvexp.so.0 -> libcsvexp.so.1.1.100

-rwxr-xr-x. 1 yashan103 yashan103 241088 Apr 1 10:46 libcsvexp.so.1.1.100

lrwxrwxrwx. 1 yashan103 yashan103 15 Apr 1 10:46 liblz4.so -> liblz4.so.1.9.3

lrwxrwxrwx. 1 yashan103 yashan103 15 Apr 1 10:46 liblz4.so.1 -> liblz4.so.1.9.3

-rw-r--r--. 1 yashan103 yashan103 236216 Apr 1 10:46 liblz4.so.1.9.3

-rwxr-xr-x. 1 yashan103 yashan103 5844176 Dec 21 2023 libnnz21.so

lrwxrwxrwx. 1 yashan103 yashan103 21 Jul 23 11:22 libocci_gcc53.so -> libocci_gcc53.so.21.1

-rwxr-xr-x. 1 yashan103 yashan103 956832 Dec 21 2023 libocci_gcc53.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 15 Jul 23 11:22 libocci.so -> libocci.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 15 Jul 23 11:22 libocci.so.10.1 -> libocci.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 15 Jul 23 11:22 libocci.so.11.1 -> libocci.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 15 Jul 23 11:22 libocci.so.12.1 -> libocci.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 15 Jul 23 11:22 libocci.so.18.1 -> libocci.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 15 Jul 23 11:22 libocci.so.19.1 -> libocci.so.21.1

lrwxrwxrwx. 1 yashan103 yashan103 15 Jul 23 11:22 libocci.so.20.1 -> libocci.so.21.1

-rwxr-xr-x. 1 yashan103 yashan103 2374808 Dec 21 2023 libocci.so.21.1

-rwxr-xr-x. 1 yashan103 yashan103 142717504 Dec 21 2023 libociei.so

-r-xr-xr-x. 1 yashan103 yashan103 153600 Dec 21 2023 libocijdbc21.so

-rwxr-xr-x. 1 yashan103 yashan103 116208 Dec 21 2023 liboramysql.so

-rw-r--r--. 1 yashan103 yashan103 771118 Apr 1 10:46 libpcre2-8.a

lrwxrwxrwx. 1 yashan103 yashan103 20 Apr 1 10:46 libpcre2-8.so -> libpcre2-8.so.0.10.4

lrwxrwxrwx. 1 yashan103 yashan103 20 Apr 1 10:46 libpcre2-8.so.0 -> libpcre2-8.so.0.10.4

-rw-r--r--. 1 yashan103 yashan103 383080 Apr 1 10:46 libpcre2-8.so.0.10.4

lrwxrwxrwx. 1 yashan103 yashan103 13 Apr 1 10:46 libssl.so -> libssl.so.1.1

-rw-r--r--. 1 yashan103 yashan103 693200 Apr 1 10:46 libssl.so.1.1

lrwxrwxrwx. 1 yashan103 yashan103 14 Apr 1 10:46 libyascli.so -> libyascli.so.0

lrwxrwxrwx. 1 yashan103 yashan103 20 Apr 1 10:46 libyascli.so.0 -> libyascli.so.1.1.100

-rwxr-xr-x. 1 yashan103 yashan103 2699208 Apr 1 10:46 libyascli.so.1.1.100

lrwxrwxrwx. 1 yashan103 yashan103 17 Apr 1 10:46 libyas_infra.so -> libyas_infra.so.0

lrwxrwxrwx. 1 yashan103 yashan103 23 Apr 1 10:46 libyas_infra.so.0 -> libyas_infra.so.1.1.100

-rwxr-xr-x. 1 yashan103 yashan103 11305496 Apr 1 10:46 libyas_infra.so.1.1.100

-rwxrwxr-x. 1 yashan103 yashan103 597808 Aug 5 22:04 libyas_oci.so

-rwxr-xr-x. 1 yashan103 yashan103 408008 Apr 1 10:46 libyex_client.so

lrwxrwxrwx. 1 yashan103 yashan103 16 Apr 1 10:46 libzstd.so -> libzstd.so.1.5.2

lrwxrwxrwx. 1 yashan103 yashan103 16 Apr 1 10:46 libzstd.so.1 -> libzstd.so.1.5.2

-rw-r--r--. 1 yashan103 yashan103 1159832 Apr 1 10:46 libzstd.so.1.5.2

drwxr-xr-x. 3 yashan103 yashan103 19 Dec 21 2023 network

-rw-r--r--. 1 yashan103 yashan103 5245454 Dec 21 2023 ojdbc11.jar

-rw-r--r--. 1 yashan103 yashan103 5153068 Dec 21 2023 ojdbc8.jar

drwxr-xr-x. 5 yashan103 yashan103 79 Dec 21 2023 sdk

-rw-r--r--. 1 yashan103 yashan103 5780 Dec 21 2023 SDK_LICENSE

-rw-rw-r--. 1 yashan103 yashan103 1628 Dec 21 2023 SDK_README

-rw-r--r--. 1 yashan103 yashan103 1805644 Dec 21 2023 ucp.jar

-rwxr-xr-x. 1 yashan103 yashan103 236176 Dec 21 2023 uidrvci

-rw-r--r--. 1 yashan103 yashan103 31869 Dec 21 2023 xstreams.jar

-rw-r--r--. 1 yashan103 yashan103 20076 Apr 1 10:46 yacli.h

准备Yashandb OCI 依赖文件

点击查看代码
[yashan103@localhost yashandb-oci-23.2.1.100-4-gecc0e02-linux-x86_64]$ pwd

/home/yashan103/oci_lib/yashandb-oci-23.2.1.100-4-gecc0e02-linux-x86_64

[yashan103@localhost yashandb-oci-23.2.1.100-4-gecc0e02-linux-x86_64]$ ll

total 600

-rwxrwxr-x. 1 yashan103 yashan103 597808 Jul 8 17:14 libyas_oci.so

-rwxrwxr-x. 1 yashan103 yashan103 13576 Jul 8 17:14 yasociconntest

执行编译命令

点击查看代码
[yashan103@localhost oci_dir]$ ll

total 32

-rw-rw-r--. 1 yashan103 yashan103 4534 Aug 5 23:03 bb.c

drwxrwxr-x. 5 yashan103 yashan103 4096 Aug 5 22:25 CMakeFiles

-rw-rw-r--. 1 yashan103 yashan103 861 Aug 5 23:05 CMakeLists.txt

-rwxrwxr-x. 1 yashan103 yashan103 15896 Aug 5 22:25 YAS_OCI_TEST

[yashan103@localhost oci_dir]$ cmake -B build .

-- Configuring done

-- Generating done

-- Build files have been written to: /home/yashan103/oci_dir

[yashan103@localhost oci_dir]$ make

Scanning dependencies of target YAS_OCI_TEST

[ 50%] Building C object CMakeFiles/YAS_OCI_TEST.dir/bb.c.o

[100%] Linking C executable YAS_OCI_TEST

[100%] Built target YAS_OCI_TEST

执行二进制软件

点击查看代码
[yashan103@localhost oci_dir]$ ./YAS_OCI_TEST

test succeed!

以一个OCI代码解释代码常用语法的含义

点击查看代码
#include <stdio.h>

#include <stdint.h>

#include <stdlib.h>

#include <string.h>

#include <oci.h>

 

 

// 调用OCI代码的CALL函数

#define OCI_TEST_CALL(ociFunc) \

    do { \

        sword r = ociFunc; \

        if (r != OCI_SUCCESS) { \

            checkerr(errhp, r); \

            return r; \

        } \

    } while (0)

 

static text* username = (text*)"sys";

static text* password = (text*)"Cod-2022";

static text* dbname = (text*)"CITEST";

 

static OCIEnv* envhp = NULL;

static OCIError* errhp = NULL;

static OCISvcCtx* svchp = NULL;

static OCISession* authp = NULL;

static OCIServer* srvhp = NULL;

 

// ## 检查代码执行是否返回异常的函数

void checkerr(OCIError* errhp, sword status)

{

    text errbuf[512];

    sb4 errcode = 0;

 

      // 根据status 判断OCI执行结果状态

    switch (status) {

        case OCI_SUCCESS:

            break;

        case OCI_SUCCESS_WITH_INFO:

            (void)printf("Error - OCI_SUCCESS_WITH_INFO\n");

            break;

        case OCI_NEED_DATA:

            (void)printf("Error - OCI_NEED_DATA\n");

            break;

        case OCI_NO_DATA:

            (void)printf("Error - OCI_NODATA\n");

            break;

        case OCI_ERROR:

            (void)OCIErrorGet((dvoid*)errhp, (ub4)1, (text*)NULL, &errcode, errbuf, (ub4)sizeof(errbuf),

                              OCI_HTYPE_ERROR);

            (void)printf("Error - %.*s\n", 512, errbuf);

            break;

        case OCI_INVALID_HANDLE:

            (void)printf("Error - OCI_INVALID_HANDLE\n");

            break;

        case OCI_STILL_EXECUTING:

            (void)printf("Error - OCI_STILL_EXECUTE\n");

            break;

        case OCI_CONTINUE:

            (void)printf("Error - OCI_CONTINUE\n");

            break;

        default:

            break;

    }

}

// 单行绑定导入数据

sword testSingleBind()

{

    OCIStmt* stmthp = NULL;

    // 申请一个句柄

    (void)OCIHandleAlloc((dvoid*)envhp, (dvoid**)&stmthp, OCI_HTYPE_STMT, (size_t)0, (dvoid**)0);

 

    OCIBind* bindp1 = NULL;

    OCIDefine* definep1 = NULL;

    ub4 intOut1[3] = {0, 1, 2};

 

    OraText* sql = "drop table if exists tbl_bind";

    // 类似JDBC的prepare statement

    //在 OCI(Oracle Call Interface)中,ub4 是 Oracle C 数据类型之一,它代表一个无符号的 4 字节(32位)整数。OCI 是 Oracle 数据库提供的编程接口,允许开发者使用 C 或 C++ 编写可以与 Oracle 数据库交互的程序。

 

    OCI_TEST_CALL(OCIStmtPrepare(stmthp, errhp, sql, (ub4)strlen((char*)sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

    // 类似JDBC的执行

    OCI_TEST_CALL(OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, NULL, NULL, OCI_DEFAULT));

 

    sql = "create table tbl_bind(col1 int, col2 varchar(20))";

    OCI_TEST_CALL(OCIStmtPrepare(stmthp, errhp, sql, (ub4)strlen((char*)sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

    OCI_TEST_CALL(OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, NULL, NULL, OCI_DEFAULT));

 

    sql = "insert into tbl_bind values (:1, '11')";

    OCI_TEST_CALL(OCIStmtPrepare(stmthp, errhp, sql, (ub4)strlen((char*)sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

    OCI_TEST_CALL(OCIBindByPos(stmthp, &bindp1, errhp, (ub4)1, (dvoid*)intOut1, (sb4)sizeof(ub4), SQLT_INT, 0, 0, 0, 0, NULL, OCI_DEFAULT));

    OCI_TEST_CALL(OCIStmtExecute(svchp, stmthp, errhp, (ub4)3, (ub4)0, NULL, NULL, OCI_DEFAULT));

    

    ub4 rowcnt;

    OCI_TEST_CALL(OCIAttrGet((CONST dvoid*)stmthp, (ub4)OCI_HTYPE_STMT, (void*)&rowcnt, (ub4*)0, (ub4)OCI_ATTR_ROW_COUNT, errhp));

    if (rowcnt != 3) {

        return OCI_ERROR;

    }

   

    // 单行取数据

    sql = "select col1 + 99 from tbl_bind";

    OCI_TEST_CALL(OCIStmtPrepare(stmthp, errhp, sql, (ub4)strlen((char*)sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

    OCI_TEST_CALL(OCIDefineByPos(stmthp, &definep1, errhp, (ub4)1, (dvoid*)intOut1, (sb4)sizeof(ub4), SQLT_INT, 0, 0, 0, OCI_DEFAULT));

    OCI_TEST_CALL(OCIStmtExecute(svchp, stmthp, errhp, (ub4)3, (ub4)0, NULL, NULL, OCI_DEFAULT));

    if (intOut1[0] != 99 || intOut1[1] != 100 || intOut1[2] != 101) {

        return OCI_ERROR;

    }

      //释放句柄

    (void)OCIHandleFree((dvoid*)stmthp, (ub4)OCI_HTYPE_STMT);

    return OCI_SUCCESS;

}

 

// 批量绑定导入数据

sword testBatchBind()

{

    OCIStmt* stmthp = NULL;

    (void)OCIHandleAlloc((dvoid*)envhp, (dvoid**)&stmthp, OCI_HTYPE_STMT, (size_t)0, (dvoid**)0);

 

    OCIBind* bindp = NULL;

    OCIDefine* definep = NULL;

 

    sb1 intIn1[4];

    sb2 ind1[4];

    ub2 rlen1[4];

 

    OraText* sql = "drop table if exists tbl_bind";

    OCI_TEST_CALL(OCIStmtPrepare(stmthp, errhp, sql, (ub4)strlen((char*)sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

    OCI_TEST_CALL(OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, NULL, NULL, OCI_DEFAULT));

 

    sql = "create table tbl_bind(col1 bigint)";

    OCI_TEST_CALL(OCIStmtPrepare(stmthp, errhp, sql, (ub4)strlen((char*)sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

    OCI_TEST_CALL(OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, NULL, NULL, OCI_DEFAULT));

 

    intIn1[0] = 0;

    intIn1[1] = 1;

    intIn1[2] = 2;

 

    ind1[0] = 0;

    ind1[1] = 0;

    ind1[2] = 0;

 

    rlen1[0] = 1;

    rlen1[1] = 1;

    rlen1[2] = 1;

 

    OraText* sql1 = "insert into tbl_bind values (:1)";

    OCI_TEST_CALL(OCIStmtPrepare(stmthp, errhp, sql1, (ub4)strlen((char*)sql1), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

    OCI_TEST_CALL(OCIBindByPos(stmthp, &bindp, errhp, (ub4)1, (dvoid*)intIn1, (sb4)sizeof(sb1), SQLT_INT, ind1, rlen1, 0, 0, NULL, OCI_DEFAULT));

    OCI_TEST_CALL(OCIStmtExecute(svchp, stmthp, errhp, (ub4)3, (ub4)0, NULL, NULL, OCI_DEFAULT));

    

    // 批量取数据

    OraText* sql2 = "select col1 from tbl_bind order by rowid";

    OCI_TEST_CALL(OCIStmtPrepare(stmthp, errhp, sql2, (ub4)strlen((char*)sql2), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

    OCI_TEST_CALL(OCIDefineByPos(stmthp, &definep, errhp, (ub4)1, (dvoid*)intIn1, (sb4)sizeof(sb1), SQLT_INT, ind1, rlen1, 0, OCI_DEFAULT));

    OCI_TEST_CALL(OCIStmtExecute(svchp, stmthp, errhp, (ub4)3, (ub4)0, NULL, NULL, OCI_DEFAULT));

 

    if (intIn1[0] != 0 || intIn1[1] != 1 || intIn1[2] != 2) {

        return OCI_ERROR;

    }

 

    if (ind1[0] != 0 || ind1[1] != 0 || ind1[2] != 0) {

        return OCI_ERROR;

    }

 

    if (rlen1[0] != 1 || rlen1[1] != 1 || rlen1[2] != 1) {

        return OCI_ERROR;

    }

    

    (void)OCIHandleFree((dvoid*)stmthp, (ub4)OCI_HTYPE_STMT);

    return OCI_SUCCESS;

}

 

// 连接数据库

sword testConnect()

{

    sword errcode = 0;

 

    errcode = OCIEnvCreate((OCIEnv**)&envhp, (ub4)OCI_THREADED, (dvoid*)0, (dvoid * (*)(dvoid*, size_t))0,

                     (dvoid * (*)(dvoid*, dvoid*, size_t))0, (void (*)(dvoid*, dvoid*))0, (size_t)0, (dvoid**)0);

 

    if (errcode != 0) {

        (void)printf("OCIEnvCreate failed with errcode = %d.\n", errcode);

        return OCI_ERROR;

    }

 

    (void)OCIHandleAlloc((dvoid*)envhp, (dvoid**)&errhp, OCI_HTYPE_ERROR, (size_t)0, (dvoid**)0);

    (void)OCIHandleAlloc((dvoid*)envhp, (dvoid**)&svchp, OCI_HTYPE_SVCCTX, (size_t)0, (dvoid**)0);

    (void)OCIHandleAlloc((dvoid*)envhp, (dvoid**)&srvhp, OCI_HTYPE_SERVER, (size_t)0, (dvoid**)0);

 

    OCI_TEST_CALL(OCIServerAttach(srvhp, errhp, (text*)dbname, (sb4)strlen((char*)dbname), 0));

    (void)OCIAttrSet((dvoid*)svchp, OCI_HTYPE_SVCCTX, (dvoid*)srvhp, (ub4)0, OCI_ATTR_SERVER, (OCIError*)errhp);

 

    (void)OCIHandleAlloc((dvoid*)envhp, (dvoid**)&authp, (ub4)OCI_HTYPE_SESSION, (size_t)0, (dvoid**)0);

    (void)OCIAttrSet((dvoid*)authp, (ub4)OCI_HTYPE_SESSION, (dvoid*)username, (ub4)strlen((char*)username), (ub4)OCI_ATTR_USERNAME, errhp);

    (void)OCIAttrSet((dvoid*)authp, (ub4)OCI_HTYPE_SESSION, (dvoid*)password, (ub4)strlen((char*)password), (ub4)OCI_ATTR_PASSWORD, errhp);

 

    OCI_TEST_CALL(OCISessionBegin(svchp, errhp, authp, OCI_CRED_RDBMS, (ub4)OCI_DEFAULT));

    (void)OCIAttrSet((dvoid*)svchp, (ub4)OCI_HTYPE_SVCCTX, (dvoid*)authp, (ub4)0, (ub4)OCI_ATTR_SESSION, errhp);

 

    return OCI_SUCCESS;

}

 

// 关闭数据库连接

sword testDisconnect()

{

    OCI_TEST_CALL(OCISessionEnd(svchp, errhp, authp, (ub4)0));

    OCI_TEST_CALL(OCIServerDetach(srvhp, errhp, (ub4)OCI_DEFAULT));

 

    (void)OCIHandleFree((dvoid*)authp, (ub4)OCI_HTYPE_SESSION);

    (void)OCIHandleFree((dvoid*)srvhp, (ub4)OCI_HTYPE_SERVER);

    (void)OCIHandleFree((dvoid*)svchp, (ub4)OCI_HTYPE_SVCCTX);

    (void)OCIHandleFree((dvoid*)errhp, (ub4)OCI_HTYPE_ERROR);

    (void)OCIHandleFree((dvoid*)envhp, (ub4)OCI_HTYPE_ENV);

 

    return OCI_SUCCESS;

}

sword runTest()

{

    if (testConnect() != OCI_SUCCESS) {

        return 1;

    }

    if (testSingleBind() != OCI_SUCCESS) {

        return 2;

    }

    if (testBatchBind() != OCI_SUCCESS) {

        return 3;

    }

    if (testDisconnect() != OCI_SUCCESS) {

        return 5;

    }

    return 0;

}

 

int main(argc, argv)

int argc;

char* argv[];

{

    sword runResult = runTest();

    if (runResult == 0) {

        printf("test succeed!\n");

    } else {

        printf("test failed! failed test num : %d\n", runResult);

    }

    return runResult;

}
参考资料

https://www.yashandb.com/newsinfo/7488285.html?templateId=1718516

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/884344.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【4.6】图搜索算法-DFS和BFS解合并二叉树

一、题目 给定两个二叉树&#xff0c;想象当你将它们中的一个覆盖到另一个上时&#xff0c;两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是 如果两个节点重叠&#xff0c;那么将他们的 值相加作为节点合并后的新值&#xff0c;否则不为 NUL L…

DERT目标检测源码流程图main.py的执行

DERT目标检测源码流程图main.py的执行 官网预测脚本 补充官网提供的预测部分的代码信息。 from PIL import Image import requests import matplotlib.pyplot as pltimport torch from torch import nn from torchvision.models import resnet50 import torchvision.transform…

网页设计html心得

一&#xff0c;认识网页 说到网页&#xff0c;其实大家并不陌生 1.1网页究竟是什么&#xff1f; 网页主要由文字、图像和超链接等元素构成。当然&#xff0c;除了这些元素&#xff0c;网页中还可以包含音频、视频以及Flash等。 1.2网页是如何形成的呢&#xff1f; 1.特殊的…

笔记整理—linux进程部分(1)进程终止函数注册、进程环境、进程虚拟地址

对于mian()函数而言&#xff0c;执行前也需要先执行一段引导代码才会去执行main()函数&#xff0c;该部分的代码包含构建c语言的运行环境等配置&#xff0c;如清理bss段等。 在使用gcc去编译程序的时候&#xff0c;使用gcc -v xxx.c可见链接过程。在编译完成后可见xxx.out文件。…

动态规划算法:12.简单多状态 dp 问题_打家劫舍_C++

目录 题目链接&#xff1a;LCR 089. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 一、题目解析 题目&#xff1a; 解析&#xff1a; 二、算法原理 1、状态表示 状态表示&#xff1a; 2、状态转移方程 状态转移方程推理&#xff1a; 3、初始化 dp表初始化: 特殊…

【优选算法】(第七篇)

目录 ⽔果成篮&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 找到字符串中所有字⺟异位词&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 ⽔果成篮&#xff08;medium&#xff09; 题目解析 1.题目链接&#xff1a;. - 力扣&#…

神经网络(一):神经网络入门

文章目录 一、神经网络1.1神经元结构1.2单层神经网络&#xff1a;单层感知机1.3两层神经网络&#xff1a;多层感知机1.4多层神经网络 二、全连接神经网络2.1基本结构2.2激活函数、前向传播、反向传播、损失函数2.2.1激活函数的意义2.2.2前向传播2.2.3损失函数、反向传播2.2.4梯…

连锁店收银系统如何选择?

在新零售背景下&#xff0c;连锁店的收银系统扮演着至关重要的角色。随着科技的不断发展和消费者需求的不断变化&#xff0c;一款功能齐全的收银系统不仅可以提高便利店的运营效率&#xff0c;还可以提供更好的消费体验。以下是连锁店收银系统必备的功能。 1.收银系统能支持独…

Mac制作Linux操作系统启动盘

前期准备 一个 Mac 电脑 一个 U 盘&#xff08;8GB 以上&#xff09; 下载好 Linux 系统镜像&#xff08;iso 文件&#xff09; 具体步骤 挂载 U 盘 解挂 U 盘 写系统镜像到 U 盘 完成 一、挂载 U 盘 首先插入 U 盘&#xff0c;打开终端输入下面的命令查看 U 盘是否已经 m…

python单例和工厂模式

设计模式 设计模式是一种编程套路&#xff0c;可以极大的方便程序的开发 最常见、最经典的设计模式&#xff0c;就是学习的面向对象 除了面向对象之外&#xff0c;在编程中也有很多既定的套路可以方便开发&#xff0c;我们称之为设计模式&#xff1a; 单例、工厂模式建造者…

IDEA2020运行项目时不从配置的maven仓库找jar包,从C盘默认路径下找jar包

目录 问题描述&#xff1a; 解决方案&#xff1a; 问题描述&#xff1a; 使用IDEA2020做java开发&#xff0c;idea的设置中maven仓库地址配在D盘&#xff0c; maven的配置文件setting.xml中的仓库也已经确认配置到D盘&#xff0c; 项目根据pom文件自动下载jar包时也会下载到…

IDEA 系列产品 下载

准备工作 下载 下载链接&#xff1a;https://www.123865.com/ps/EF7OTd-mbHnH 仅供参考 环境 演示环境&#xff1a; 操作系统&#xff1a;windows10 产品&#xff1a;IntelliJ IDEA 版本&#xff1a;2024.1.2 注意&#xff1a;如果需要其他产品或者版本可以自行下载&#xff0…

【算法系列-数组】移除元素 (双指针)

【算法系列-数组】移除元素 (双指针) 文章目录 【算法系列-数组】移除元素 (双指针)1. 算法分析&#x1f6f8;2. 删除有序数组中的重复性(LeetCode 26)2.1 解题思路&#x1f3af;2.2 解题过程&#x1f3ac;2.3 代码举例&#x1f330; 3. 移动零(LeetCode 283)3.1 解题思路&…

黑马智数Day4-1

新增月卡 配置路由完成跳转 {path: /cardAdd,component: () > import(/views/car/car-card/add-card) }<el-button type"primary" click"$router.push(/cardAdd)">添加月卡</el-button> 车辆信息表单验证 <el-form :model"carInf…

【移植】一种快速移植OpenHarmony Linux内核的方法

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 移植概述 本文面向希望将 OpenHarmony 移植到三方芯片平台硬件的开…

接档《凡人修仙传》的《牧神记》动画,能否成为黑马?

堪称B站国创半边天的《凡人修仙传》第三季将在10月19日迎来完结&#xff0c;接档它的是由玄机科技制作&#xff0c;改编自宅猪同名网络小说的《牧神记》。这部将于10月27日播出的“玄机娘娘新崽”&#xff0c;能否成功接下《凡人修仙传》的好彩头&#xff0c;成为国漫界下一匹黑…

LeetCode[中等] 78.子集

给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的 子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 思路 迭代法 每次遍历nums中的新的数&#xff0c;将其加到之前所有得到的set中&#xff0c…

【第十六章:Sentosa_DSML社区版-机器学习之生存分析】

【第十六章&#xff1a;Sentosa_DSML社区版-机器学习之生存分析】 16.1 加速失效时间回归 1.算子介绍 加速失效时间回归模型Accelerated failure time (AFT)是一个监督型参数化的回归模型&#xff0c;它可以处理删失数据。它描述了一个生存时间的对数模型&#xff0c;所以它通…

深度解读 2024 Gartner DevOps 魔力象限

上周 Gartner 刚发布了 2024 年度的 DevOps 魔力象限。我们也第一时间来深度解读一下这份行业里最权威的报告。 和2023年对比 23 年入围 14 家厂商&#xff0c;24 年入围 11 家。4 家厂商从报告中消失&#xff0c;分别是 Bitrise, Codefresh, Google Cloud Platform (GCP), VM…

SpringBoot集成Redis及SpringCache缓存管理

1.集成Redis 1.导入依赖 <!--spirngboot springdata对redis支持--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2.配置信息 #数据源配置…