pro*c中关于clob的存取

来源:互联网 发布:福禄克网络测试仪 编辑:程序博客网 时间:2024/04/28 18:05

     最近在做一个关于矢量图型化的电力图型软件,服务器需要用proc进行开发,但是关于proc读取clob方面资料很少,下面是关于clob读写方面的经验。

     首先,我们先来看看如何读取clob中的信息,见一下代码:

这一段代码是通过动态的sql语句进行select的查询,

 * 输    入 : *strSql          动态sql语句,只能有一个clob字段(SELECT  CLOBVALUE FROM EMP WHERE BH=1001)
          
 * 输    出 :  **arr           clob取出来的字符串内容,用指针的指针是为了可以从新分配内存

int read_clob_sql(char *strSql,char  **arr)
{
 int size ;
 char *xml,*charTmp;
 if((xml= (char *)tpalloc("STRING", NULL, 1024))==NULL)//我通过tuxedo中间件提供的内存分配机制进行分配,也可以使用malloc进行分配。
 {
  return  _Error;
 }
 memset(xml,'/0',1024);
        OCIClobLocator *cl;
 EXEC SQL ALLOCATE :cl ;
        EXEC SQL PREPARE QuerySql FROM :strSql;
 EXEC SQL DECLARE CUR_QuerySql CURSOR FOR QuerySql;
 EXEC SQL OPEN CUR_QuerySql;
 if(sqlca.sqlcode)
 {
  return  sqlca.sqlcode;
 }
 EXEC SQL FETCH CUR_QuerySql INTO :cl;
 EXEC SQL LOB  OPEN  :cl READ;
 if(sqlca.sqlcode)
 {
  return  sqlca.sqlcode;
 }
 int iRet = read_Clob_info(cl,&xml);//获取clob里面的内容,见下面的该方法
 if( iRet)
 {
  return  iRet;
 }
 size = strlen(xml)+1;
        charTmp = *arr;
 *arr = (char *)tpalloc("STRING", NULL, 1024);//我必须在close clob的时候先把xml内容拷贝出来,不然close clob后内容会被释放了
 memset(*arr,'/0',size);
 tpfree(charTmp); //tuxedo的释放内存方法,你可以用free    
 strcpy(*arr,xml); 
 EXEC SQL LOB CLOSE :cl;//这里一定的关闭clob,不然会有问题的;
 EXEC SQL FREE :cl;
 EXEC SQL CLOSE CUR_QuerySql;
 tpfree(xml);
 return sqlca.sqlcode ;
}

read_Clob_info:

 * 输    入 : *a_clob   clob字段变量
          
 * 输    出 :  **xml           clob取出来的xml字符串 

int read_Clob_info(OCIClobLocator *a_clob,char  **xml)
{
 int amount;
 int size = 1024;
 EXEC SQL LOB DESCRIBE :a_clob GET LENGTH INTO :amount;//获取clob内容的长度
 if(sqlca.sqlcode)
 {
        
  return sqlca.sqlcode;
 }
 /****************有时候amount取得不准,需要加长值********问题未解决******/
 if(amount<10240){//我设定的内存块最小是10k大小,如果不这样会有些问题。
  amount=10240;
 }
 if(amount>0){
  printf("amount=%d/n",amount);
  pmsRealloc_Clob(xml, amount, size);//我自定义的内存从分配,可以根据自己的情况编写该方法
  
  EXEC SQL WHENEVER NOT FOUND CONTINUE;//这一行没有什么作用,因为在下面的if语句中已经进行了控制
  
  EXEC SQL LOB READ :amount FROM :a_clob INTO :*xml WITH LENGTH :amount;
  
  if(sqlca.sqlcode==NOTFOUND)//判断是否到结尾
  {
   return 0;
  }
 } 
 return sqlca.sqlcode;
}
以上是如果读取clob的方法过程,下面我要写关于写入clob的方法,见下面的代码:
write_clob_sql:
 * 输    入 : *strSql          动态sql语句,只能有一个clob字段(select  clobvalue from emp where bh = 1001 for update)使用更新的时候必须要用到for update,在进行insert语句的时候,对clob字段进行empty_clob()插入。           
 * 输    出 :  **arr           clob写入的xml字符串
int write_clob_sql(char *strSql,char  *arr)
{
        OCIClobLocator  *clob;
 EXEC SQL ALLOCATE :clob;
        EXEC SQL PREPARE WriteSql FROM :strSql;
 EXEC SQL DECLARE CUR_WriteSql CURSOR FOR WriteSql;
 EXEC SQL OPEN CUR_WriteSql;
 if(sqlca.sqlcode)
 {
             
  return  sqlca.sqlcode;
 }
 EXEC SQL FETCH CUR_WriteSql INTO :clob;
 EXEC SQL LOB  OPEN  :clob READ WRITE;//必须用READ WRITE打开,不然会报错的
 if(sqlca.sqlcode)
 {
  
  return  sqlca.sqlcode;
 }
 int iRet =  AppendToClob(clob,arr); //将clob进行插入方法,见下面
 EXEC SQL LOB CLOSE :clob;
        EXEC SQL FREE :clob;
 EXEC SQL CLOSE CUR_WriteSql;
 return iRet ;
}
AppendToClob:
 * 输    入 : *a_clob   clob字段变量
                    *charbuf           clob写入的xml字符串
int AppendToClob( OCIClobLocator *a_clob,  char *charbuf)
{
  ub4 ClobLen, WriteAmt, Offset;
  int CharLen = strlen(charbuf);
  int NewCharbufLen = CharLen + DATELENGTH + 4;
  varchar *NewCharbuf;
  NewCharbuf = (varchar *)malloc(2 + NewCharbufLen);
  memset(NewCharbuf, '/0', NewCharbufLen);
  strcat((char *)NewCharbuf->arr, charbuf);
  NewCharbuf->arr[CharLen + 1] = '/0';
  NewCharbuf->len = NewCharbufLen;
  EXEC SQL LOB DESCRIBE :a_clob GET LENGTH INTO :ClobLen;
   if(sqlca.sqlcode)
    {
        return  sqlca.sqlcode;
    }
   WriteAmt = NewCharbufLen;
   Offset = ClobLen + 1;
    EXEC SQL LOB WRITE ONE :WriteAmt FROM :NewCharbuf
    WITH LENGTH :NewCharbufLen INTO :a_clob AT :Offset;
  free(NewCharbuf);
  return sqlca.sqlcode;
}
 
以上是对clob的读写方法,欢迎大家进行指正。

原创粉丝点击