使用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页面:
随机推荐
- Kafka文件的存储机制
Kafka文件的存储机制 同一个topic下有多个不同的partition,每个partition为一个目录,partition命名的规则是topic的名称加上一个序号,序号从0开始. 每一个part ...
- DRUID连接池的实用 配置详解
DRUID介绍 DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0.DBCP.PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针 ...
- enum类型
1.设有变量a,b,c被说明为上述的weekday,可采用下述任一种方式: enum weekday{sun,mon,tue,wed,thu,fri,sat}; enum weekday a,b,c; ...
- 使用fragmenttabhost后,子fragment怎么获取ID?怎么用getSharedPreferences
使用fragmenttabhost后,子fragment怎么获取ID?怎么用getSharedPreferences public View onCreateView(LayoutInflater i ...
- graph-tool文档(一)- 快速开始使用Graph-tool - 2.属性映射、图的IO和Price网络
目录: 属性映射 -- 内部属性映射 图的I/O 构建一个 Price网络(例) 名词解释: Property maps:属性映射 PropertyMap:一个类 scalar value types ...
- xcode 真机调试 failed to get the task for process xxx
xcode 真机调试 failed to get the task for process xxx 此错误原因是,使用 in house profile 签名了真机调试的证书: 在 target--- ...
- 一个比较全面的java随机数据生成工具包
最近,由于一个项目的原因需要使用一些随机数据做测试,于是写了一个随机数据生成工具,ExtraRanom.可以看成是Java官方Random类的扩展,主要用于主要用于测试程序.生成密码.设计抽奖程序等情 ...
- quartz定时任务框架的使用
quartz定时任务时间设置 这些星号由左到右按顺序代表 : * * * * * * * ...
- 设置pictureBox的边框颜色
private void pictureBox2_Paint(object sender, PaintEventArgs e) { PictureBox p = (PictureBox)sender; ...
- WANL标准组织介绍-02
无线电管理委员会 FCC ETSI IEEE Wi-Fi IETF WAPI 国家无线电管理委员会认证 国家无线电管理委员会认证(State Radio Regulatory Commission o ...