使用OCI向Oracle插入Geometry数据
使用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数据的更多相关文章
- oracle 插入表数据的4种方式
1.往表中插入一整行数据 /*方法一*/ INSERT INTO 表名 VALUES(val1,val2,val3,...); /*方法二*/ '; 如: ,, FROM DUAL; 注意: 2. ...
- Oracle插入中文数据乱码 设置服务器编码和客户端编码一致
- oracle插入字符串数据时,字符串中有'单引号
使用insert into(field1,field2...) values('val1','val2'...)时,若值中有单引号时会报错. 处理方法:判断一下val1,val2中是否含有单引号,若含 ...
- ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法
ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法 语法 第一种: 通过使用Oracle语句块 --指定文档所有部门都能查看 declare cursor TABLE_DEPT and ...
- Oracle 插入数据效率对比
oracle插入数据有多种方式: 将从多个表中查出来的数据插入到临时表中 数据行数 5189597 1.传统方式:直接将数据插入到表中 insert into LLB_BASIC_USER_D_TEM ...
- 在mysql数据库中创建oracle scott用户的四个表及插入初始化数据
在mysql数据库中创建oracle scott用户的四个表及插入初始化数据 /* 功能:创建 scott 数据库中的 dept 表 */ create table dept( deptno int ...
- ThinkPHP 3.2.3+ORACLE插入数据BUG修复及支持获取自增Id的上次记录
TP+ORACLE插入数据BUG修复以及获取自增Id支持getLastInsID方法 这些天在做Api接口时候,发现用TP操作Oracle数据库,发现查询修改删除都能执行, 但一旦执行插入操作老是报错 ...
- Oracle 函数 “把当前的用户(审核人,审核通过后)插入到数据表中”
create or replace function mcode_apply_update_personnel(p_mca_no VARCHAR2, -- 参数(实参) p_action VARCHA ...
- 003杰信-在jsp页面输入数据,然后在oracle数据库中插入factory数据,当字段允许为空时要特殊处理
本博客的内容全部来自于传智播客,特在此说明. 业务要求如下:在jsp页面(jFactoryCreate.jsp)上输入数据时,转到后台,并输入到数据库. jFactoryCreate.jsp页面:
随机推荐
- hdu5785(极角排序求所有锐角钝角个数)
做法很显然,求出所有的锐角和钝角就能求出有多少个锐角三角形了. 我用了愚钝的方法,写了两三个小时... 看了下别人简单的代码.学习了下做法. sort(temp+,temp+cnt+);//排序 Fo ...
- Bootstrap的粗体和斜体
一.粗体 粗体就是给文本加粗,在普通的元素中我们一般通过font-weight设置为bold关键词给文本加粗. 在Bootstrap中,可以使用<b>和<strong>标签让文 ...
- Maven最佳实践:划分模块
http://juvenshun.iteye.com/blog/305865 ************************************* "分天下为三十六郡,郡置守,尉,监& ...
- 转载 - LINUX下查看CPU使用率的命令
几个常用的命令,一些不错的解释 http://blog.csdn.net/wengpingbo/article/details/6302058 1.top 使用权限:所有使用者 使用方式:top [- ...
- scala调用java的方法,返回了一个对象链表List<Student>,在scala中遍历该链表获取指定Student的名字name
假设Student类如下: class Student { private int no; private String name; public int getNo() { return no; } ...
- 转! java 中“==” 与“ .equals ”比较
在java程序设计中,经常需要比较两个变量值是否相等.例如1.简单数据类型比较a = 10;b = 10;if(a == b){//写要执行的代码}2.引用数据类型比较ClassA a = new C ...
- eclipse+adt+sdk开发环境搭配
1.开发环境配置 http://www.mamicode.com/info-detail-516839.html
- genymotion是一款完全超越BlueStacks
今天给大家推荐一款超赞的神器:genymotion. 一:什么是genymotion genymotion是一款完全超越BlueStacks的安卓模拟器,正如它中文官网的介绍:快到极致的An ...
- sessionStorage
for(i=0;i<tkt.length;i++){ if(tkt[i].redEnvelopeType==1){ full1+="<div class='pic_01' id= ...
- IE6 IE7 hasLayout bug之li间的3px垂直间距
1. li中仅包含a,span等内联(行内)元素2.触发条件: li元素的layout被触发(通常为设置了宽或高,设置overflow:hidden在IE7下同样触发layout),且a或span元素 ...