原先是php+mysql,现在要换成php+oracle将原mysql中 text, medium text类型转为oracle中的 clob类型现在需要将数据导入至oracle中,原mysql中有很字段的大小,超过了4000字符
插入oracle中总是报错,说超出范围clob最大能存储是4g怎样才能解决?

解决方案 »

  1.   

    如果楼主接触过mysql的话一定对mysql的text和blob不会陌生,在mysql中是直接操作text和blob的。但是在oracle中,它把lob做为一种特殊的字段,不能直接进行操作--比如不能直接插入到lob字段中,也不能用like查询等等。   
      这里是我保存的一篇这方面的文章,原文搬过来,由于保存的时候只是取了一部分,没头没尾的,所以没法找到原来的出处。   
        
      不能直接用INSERT语句向LOB字段中插入值。一般情况下,有如下的几步:     
      1   先分析一个INSERT语句,返回一个LOB的描述符     
      2   用OCI函数生成一个本地的LOB对象     
      3   将LOB对象绑定到LOB描述符上     
      4   执行INSERT语句     
      5   给LOB对象赋值     
      6   释放LOB对象和SQL语句句柄     
        
      下面的这个例子是把用户上传的图片文件存放到BLOB(或BFILE中,操作稍有不同)中。     
      首先要建一个表,结构如下:     
      CREATE   TABLE   PICTURES   (     
      ID   NUMBER,     
      DESCRIPTION   VARCHAR2(100),     
      MIME   VARCHAR2(128),     
      PICTURE   BLOB     
      );     
      如果要实现ID的自动增加,再建一个SEQUENCE:     
      CREATE   SEQUENCE   PIC_SEQ;     
        
      然后是用来处理数据的PHP程序代码。     
      <?php     
        
      //建立Oracle数据库连接     
      $conn   =   OCILogon($user,   $password,   $SID);     
      //提交SQL语句给Oracle     
      //在这里要注意的两点:一是用EMPTY_BLOB()函数。这是Oracle的内部函数,返回一个LOB的定位符。在插入LOB时,只能用这个办法先生成一个空的LOB定位符,然后对这个定位符进行操作。EMPTY_BLOB()函数是针对BLOB类型的,对应于CLOB的是EMPTY_CLOB()。二是RETURNING后面的部分,把picture返回,让PHP的OCI函数能够处理。     
      $stmt   =   OCIParse($conn,"INSERT   INTO   PICTURES   (id,   description,   picture)     
      VALUES   (pic_seq.NEXTVAL,   '$description',   '$lob_upload_type',   EMPTY_BLOB())   RETURNING   picture   INTO   :PICTURE");     
      //生成一个本地LOB对象的描述符。注意函数的第二个参数:OCI_D_LOB,表示生成一个LOB对象。其它可能的还有OCI_D_FILE和OCI_D_ROWID,分别对应于BFILE和ROWID对象。     
      $lob   =   OCINewDescriptor($conn,   OCI_D_LOB);     
      //将生成的LOB对象绑定到前面SQL语句返回的定位符上。     
      OCIBindByName($stmt,   ':PICTURE',   &$lob,   -1,   OCI_B_BLOB);     
      OCIExecute($stmt);     
      //向LOB对象中存入数据。因为这里的源数据是一个文件,所以直接用LOB对象的savefile()方法。LOB对象的其它方法还有:save()和load(),分别用来保存和取出数据。但BFILE类型只有一个方法就是save()     
      if($lob->savefile($lob_upload)){     
      OCICommit($conn);     
      echo   "上传成功   
      ";     
      }else{     
      echo   "上传失败   
      ";     
      }     
      //释放LOB对象     
      OCIFreeDesc($lob);     
      OCIFreeStatement($stmt);     
      OCILogoff($conn);     
        
      ?>     
        
      还有一个要注意的地方:LOB字段的值最少要1个字符,所以在save()或savefile()之前,要确保值不能为空。否则,Oracle会出错。     
        
      取出     
        
      对一个LOB中取出数据,有两种办法。一是生成一个LOB对象,然后绑定到一条SELECT语句返回的定位符上,再用LOB对象的load()方法取出数据;二是直接用PHP的OCIFetch***函数。第一种方法比第二种方法要麻烦得多,所以我直接说说第二种方法。     
        
      还是用上面的表。     
        
      <?php     
      $conn   =   OCILogon($user,   $password,   $SID);     
      $stmt   =   OCIParse($conn,"SELECT   *   FROM   PICTURES   WHERE   ID=$pictureid");     
      OCIExecute($stmt);     
      //秘密就在PCIFetchInfo的第三个参数上:OCI_RETURN_LOBS。第三个参数是FETCH的模式,如果OCI_RETURN_LOBS,就直接把LOB的值放到结果数组中,而不是LOB定位符,也就不用LOB对象的load()方法了。     
      if   (OCIFetchInto($stmt,   $result,   OCI_ASSOC+OCI_RETURN_LOBS))     
      {     
      echo   "Content-type:   "   .   StripSlashes($result[MIME]);     
      echo   StripSlashes($result[PICTURE]);     
      }     
      OCIFreeStatement($stmt);     
      OCILogoff($conn);     
      ?>     
        
      这个程序用来显示放在LOB中的数据(图片)。调用方法(假设脚本名是getpicture.php):     
      <IMG   SRC="getpicture.php?pictureid=99"   ALT="放在Oracle   LOB中的图片">     
        
      查询     
        
      前面已经提了下,对于Oracle的LOB字段是不能用LIKE进行匹配的。怎么办呢?其实并不复杂,Oracle有一个匿名的程序包,叫DBMS_LOB,里面有所有的操作LOB所需的过程。     
        
      假设有象这样一个表:     
      CREATE   TABLE   ARTICLES   (     
      ID   NUMBER,     
      TITLE   VARCHAR2(100),     
      CONTENT   CLOB     
      );     
        
      文章的内容放在CONTENT字段中。     
        
      现在我们要找出所以内容中包含"PHP中文用户"的文章,可以这么来做:     
        
      <?php     
      $conn   =   OCILogon($user,   $password,   $SID);     
      //WHERE子句中用了DBMS_LOB.INSTR过程。它有四个参数,前面两个分别表示LOB的定位符(可以直接用字段表示)和要查找的字符串;后面两个分别表示开始的偏移量和出现的次数。要注意的是必须判断它的返回值,也就是要大于0。     
      $stmt   =   OCIParse($conn,"SELECT   *   FROM   ARTICLES   WHERE   DBMS_LOB.INSTR(CONTENT,   'PHP中文用户',   1,   1)   >   0");     
      OCIExecute($stmt);     
      if   (OCIFetchInto($stmt,   $result,   OCI_ASSOC+OCI_RETURN_LOBS))     
      {     
      ...     
      }     
      OCIFreeStatement($stmt);     
      OCILogoff($conn);     
      ?>     
        
      

  2.   

    RETURNING  picture  INTO  :PICTURE");    
    这句话什么意思啊?