使用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. linux 静态库、共享库

    http://blog.chinaunix.net/uid-26833883-id-3219335.html http://blog.chinaunix.net/uid-23069658-id-314 ...

  2. Sqlserver_insert语法

    1. INSERT INTO SELECT 通过 SQL,您可以从一个表复制信息到另一个表.   INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中. 我们可 ...

  3. Linux命令(2) - 查看目录和文件大小: du -sh

    [root@hadoop01 ~]# ll total 156 drwxr-xr-x. 18 root root 4096 Jan 5 05:05 apps -rw-r--r--. 1 root ro ...

  4. Html表单的正则校验--将不符合指定正则表达式的字符串自动替换为空

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  5. 2D客户端+微端技术总结

    本人于2013年9月23号加入一个页游项目组, 并作为项目组的客户端小组的主程, 带领一个4个人(峰值)的前端小组, 进行微端的开发.微端项目于2014年8月底大体完成, 历时11个月.9月份之后微端 ...

  6. 【CITE】当类库项目中无法使用Application.StartupPath的时侯 (注:主要是在进行反射读取文件的时候!!)

    http://jcserver.blog.163.com/blog/static/24044859200851582354135/ 通常我们WinForm编程时,要获取程序当 前运行的文件夹路径会用A ...

  7. C# winform程序怎么打包成安装项目(图解)

    1:新建安装部署项目 打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装向导(安装项目也一样),然后点击确定.(详细见下图) 此主题相关图片如下: 2:安装向导 关闭后打开安 ...

  8. java操作字符串,重点是记录一次使用replaceAll对字符串的操作

    符串常用操作(String类) 字符串查找 String提供了两种查找字符串的方法,即indexOf与lastIndexOf方法. 1.indexOf(String s) 该方法用于返回参数字符串s在 ...

  9. XAML-1

    1.XAML Extension Application Marked Language,是WPF技术中专门用来设计UI的语言.XAML是从XML派生出来的,是一种声明式语言,当你看到一个标签,就是声 ...

  10. quartz Web项目基础最简单配置

    web方面的quartz 配置资料,从网上搜索出来的很难找到完整可用的代码样例.自己上传一个. IDE:Intellij tomcat jdk1.7 quartz 2.1.5 这里下载: http:/ ...