使用C/C++操作Oracle数据库,使用OCI可谓是最强大,当然也是最难的方式。Oracle是一个功能复杂而强大的数据库,它可以很好的支持空间数据(Oracle spatial)。如何使用OCI向Oracle数据库中插入空间数据(SDO_GEOMETRY字段)呢,本文将给出代码。

首先,给出OCI连接数据库的代码:(ph开头的变量均是OCI句柄)

 //以指定的模式创建环境句柄
OCIEnvCreate(&phEnv,connMode,(dvoid *),,,,(size_t),(dvoid **));
//分配服务器句柄,注意不要少了取值符号&
OCIHandleAlloc((dvoid *)phEnv,(dvoid **)&phServer,OCI_HTYPE_SERVER,,(dvoid **));
//分配错误句柄
OCIHandleAlloc((dvoid *)phEnv,(dvoid **)&phErr,OCI_HTYPE_ERROR,,(dvoid **));
//创建服务器上下文句柄,c_str()函数将C++类型的string字符串转化为C串 char*
if(OCIServerAttach(phServer,phErr,(text *)DBname.c_str(),strlen(DBname.c_str()),OCI_DEFAULT) ==OCI_SUCCESS)
cout<<"DB "+DBname+" is connected successfully!"<<endl;
else
{
cout<<"DB "+DBname+" is fail to connect,Please check whether you type a right DB name!"<<endl;
}
//分配上下文句柄
OCIHandleAlloc((dvoid *)phEnv,(dvoid **)&phSvcCtx,OCI_HTYPE_SVCCTX,,(dvoid **));
//设置服务器上下文句柄的服务器句柄属性
OCIAttrSet((dvoid *)phSvcCtx,OCI_HTYPE_SVCCTX,(dvoid *)phServer,(ub4),OCI_ATTR_SERVER,phErr);
//分配用户会话句柄
OCIHandleAlloc((dvoid *)phEnv,(dvoid **)&phSession,OCI_HTYPE_SESSION,,(dvoid **));
//为用户会话句柄设置用户名和密码属性
OCIAttrSet((dvoid *)phSession,OCI_HTYPE_SESSION,(dvoid *)username.c_str(),(ub4)strlen(username.c_str()),OCI_ATTR_USERNAME,phErr);
OCIAttrSet((dvoid *)phSession,OCI_HTYPE_SESSION,(dvoid *)password.c_str(),(ub4)strlen(password.c_str()),OCI_ATTR_PASSWORD,phErr);
//申请描述句柄
OCIHandleAlloc((dvoid*)phEnv,(dvoid**)&phdsc,OCI_HTYPE_DESCRIBE,,(void**));
if (OCISessionBegin(phSvcCtx,phErr,phSession,OCI_CRED_RDBMS,OCI_DEFAULT)==OCI_SUCCESS)
{
cout<<"user session is created successfully!"<<endl;
}
else
{
cout<<"user session is fail to create! "<<endl;
}
//在服务器上下文环境中设置用户会话属性
OCIAttrSet((dvoid *)phSvcCtx, OCI_HTYPE_SVCCTX,(dvoid *)phSession,(ub4) ,OCI_ATTR_SESSION,phErr);

接下来进行数据插入:

//HYARRAYT型指针
OCIType * ordinates_tdo =NULL;
//HYARRAYT的类型映射OCIARRAY
OCIArray * hyarray_Point =NULL;
//HYARRAYT的类型映射OCIARRAY
OCIArray * hyarray_MBR =NULL;
OCINumber oci_number;
//声明绑定
OCIBind* bndhp1 = NULL;
OCIBind* bndhp2 = NULL;
//创建用于描述SDO_ORDINATE_ARRAY类型的描述符
ordinates_tdo = get_tdo(SDO_ORDINATE_ARRAY);
//分配语句句柄
CheckErr(phErr,OCIHandleAlloc(phEnv,(void **)&phStmt,OCI_HTYPE_STMT,,));
string sql_str ="";
sql_str = "INSERT INTO "+table+" VALUES(:1,SDO_GEOMETRY(2002,NULL,NULL,SDO_ELEM_INFO_ARRAY( 1,2,1),:ordinates))"
text * insert = (text*)sql_str.c_str();
//准备SQL语句
CheckErr(phErr,OCIStmtPrepare(phStmt,phErr,insert,strlen((char *)insert),OCI_NTV_SYNTAX,OCI_DEFAULT)); //变长数组类型的初始化,初始化SDO_ORDINATE_ARRAY
CheckErr(phErr,OCIObjectNew(phEnv,phErr,phSvcCtx,OCI_TYPECODE_VARRAY,ordinates_tdo,(dvoid*)NULL,OCI_DURATION_SESSION,FALSE,(dvoid**)&hyarray_Point));
vector<trackpoint> pointSet = track.getPointSet();
//输入坐标值 (linestring)
for (int i=;i<pointSet.size();i++)
{
CheckErr(phErr,OCINumberFromReal(phErr,(dvoid*)&pointSet[i].lon,(uword)sizeof(double),&oci_number));
CheckErr(phErr,OCICollAppend(phEnv,phErr,(dvoid*)&oci_number,(dvoid*),(OCIColl*)hyarray_Point));
CheckErr(phErr,OCINumberFromReal(phErr,(dvoid*)&pointSet[i].lat,(uword)sizeof(double),&oci_number));
CheckErr(phErr,OCICollAppend(phEnv,phErr,(dvoid*)&oci_number,(dvoid*),(OCIColl*)hyarray_Point));
}
//绑定变量
CheckErr(phErr,OCIBindByPos(phStmt,&bndhp1,phErr,,&nid,sizeof(int),SQLT_FLT,,,,,,OCI_DEFAULT));
//变量绑定,此处为坐标
CheckErr(phErr,OCIBindByName(phStmt,&bndhp1,phErr,(text*)":ordinates",(sb4)-,(dvoid*),(sb4),SQLT_NTY,(dvoid*),(ub2*),(ub2*),(ub4),(ub4*),(ub4)OCI_DEFAULT));
CheckErr(phErr,OCIBindObject(bndhp1,phErr,ordinates_tdo,(dvoid**)&hyarray_Point,(ub4*),(dvoid**),(ub4*)));
//执行SQL语句
CheckErr(phErr,OCIStmtExecute(phSvcCtx,phStmt,phErr,,,NULL,NULL,OCI_DEFAULT));
OCITransCommit(phSvcCtx,phErr,(ub4));

应该注意的是Oracle spatial的SDO_GEOMETRY字段,它的构建方式为:

SDO_GEOMETRY(

2002  --表示集合类型,此处为线串

NULL  --表示坐标系

NULL  -- 表示点的类型

SDO_ELEM_INFO_ARRAY(1,2,1) --表示几何的属性

SDO_ORDINATE_ARRAY   --表示几何类型的坐标

(

x1,x2,

x3,x4,

.....

xn,xn+1

)

)

以上具体可查看Oracle官方文档。

使用OCI向Oracle插入Geometry数据的更多相关文章

  1. oracle 插入表数据的4种方式

      1.往表中插入一整行数据 /*方法一*/ INSERT INTO 表名 VALUES(val1,val2,val3,...); /*方法二*/ '; 如: ,, FROM DUAL; 注意: 2. ...

  2. Oracle插入中文数据乱码 设置服务器编码和客户端编码一致

  3. oracle插入字符串数据时,字符串中有'单引号

    使用insert into(field1,field2...) values('val1','val2'...)时,若值中有单引号时会报错. 处理方法:判断一下val1,val2中是否含有单引号,若含 ...

  4. ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法

    ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法 语法 第一种: 通过使用Oracle语句块  --指定文档所有部门都能查看 declare cursor TABLE_DEPT and ...

  5. Oracle 插入数据效率对比

    oracle插入数据有多种方式: 将从多个表中查出来的数据插入到临时表中 数据行数 5189597 1.传统方式:直接将数据插入到表中 insert into LLB_BASIC_USER_D_TEM ...

  6. 在mysql数据库中创建oracle scott用户的四个表及插入初始化数据

    在mysql数据库中创建oracle scott用户的四个表及插入初始化数据 /* 功能:创建 scott 数据库中的 dept 表 */ create table dept( deptno int ...

  7. ThinkPHP 3.2.3+ORACLE插入数据BUG修复及支持获取自增Id的上次记录

    TP+ORACLE插入数据BUG修复以及获取自增Id支持getLastInsID方法 这些天在做Api接口时候,发现用TP操作Oracle数据库,发现查询修改删除都能执行, 但一旦执行插入操作老是报错 ...

  8. Oracle 函数 “把当前的用户(审核人,审核通过后)插入到数据表中”

    create or replace function mcode_apply_update_personnel(p_mca_no VARCHAR2, -- 参数(实参) p_action VARCHA ...

  9. 003杰信-在jsp页面输入数据,然后在oracle数据库中插入factory数据,当字段允许为空时要特殊处理

    本博客的内容全部来自于传智播客,特在此说明. 业务要求如下:在jsp页面(jFactoryCreate.jsp)上输入数据时,转到后台,并输入到数据库. jFactoryCreate.jsp页面:

随机推荐

  1. 转:strcat与strcpy与strcmp与strlen

    转自:http://blog.chinaunix.net/uid-24194439-id-90782.html strcat 原型:extern char *strcat(char *dest,cha ...

  2. JavaScript数学揭密之函数与勾股定理

    一.函数 function show(n){ return n*2; } alert( show(2) ); alert( show(3) ); alert( show(4) ); 二.勾股定理 1. ...

  3. Sqlserver_时间用法

    函数 描述 GETDATE() 返回当前的日期和时间 DATEPART() 返回日期/时间的单独部分 DATEADD() 在日期中添加或减去指定的时间间隔 DATEDIFF() 返回两个日期之间的时间 ...

  4. 串行通讯之Qt

    目录 第1章 Qt 串行通讯    1 1.1 配置.pro文件    1 1.2 查询串口信息    1 1.3 配置.打开串口    3 1.4 setRequestToSend在Windows上 ...

  5. docker居然需要3.10以上的内核

    本来想用下docker来安装部署多个MySQL实例呢,居然发现其需要3.10以上内核,对于使用centos6的人来说,是不能满足的. https://docs.docker.com/installat ...

  6. 【转】 C++中delete和delete[]的区别

    一直对C++中的delete和delete[]的区别不甚了解,今天遇到了,上网查了一下,得出了结论.做个备份,以免丢失. C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete ...

  7. noip赛前小结3

    嗯,这是第三份小结. 连续三天的小结. 这几天状态逐渐回来了. 前天3道题rk8左右. 昨天上午3道题rk7,但是有一道题考后1minAC了. 昨天晚上2道题AK了. 今天也3道题rk1了. 这个趋势 ...

  8. 20145218 《Java程序设计》第9周学习总结

    20145218 <Java程序设计>第9周学习总结 教材学习内容总结 16.1.1 JDBC简介 JDBC全名Java DataBase Connectivity,是java联机数据库的 ...

  9. Disable SELinux CentOS 7

    Disable SELinux CentOS 7 This blog covers the basic steps to disable SELinux on CentOS 7 first we ne ...

  10. postgresql 视图

    一.创建视图 create or replace view vw_users as select * from users; 二.通过定义规则来更新视图 create rule vw_users_up ...