• ORA-01461: can bind a LONG value only for insert into a LONG column


    oracle clob字段在用常规 新增或修改数据库时 如果字符超过4000(一个中文两个字符) 就会报这个错,解决办法是采用预处理的方式,单独对clob类型字段进行预处理存储,如下

    调用方式:

    $result = doClob( 'table_name',$clob_data,'update',"id=123");

    封装公共函数:

    function doClob( $table, $data, $type = 'update', $wherestr = null ,$seqname = null){
        import('Org.Util.Ociclob');
        $clog_obj= new ThinkOciclob($table, $data);
        $clog_obj->table = $table;
        $clog_obj->data= $data;
        if( strtolower( $type ) == 'update'){
            $clog_obj->where= $wherestr;
            $flag = $clog_obj->update();
        }else if(strtolower( $type ) == 'insert' ){
            $clog_obj->seqname= strtoupper($seqname);
            $flag = $clog_obj->insert();
        }
        return $flag;
    }

    引入类的方式:

    Ociclob类代码

    <?php
    namespace Think;
    class Ociclob{
    
        public $conn = false ;
        public $table = '' ;
        public $seqname = '' ;
        public $where = '' ;
        public $lob = '' ;
        public $data = '' ;
    
        function  __construct(){
            $this->conn = $this->db_connect();
            if(!empty($table)) $this->table=$table;
            if(!empty($table)&&!empty($data)){
                $this->checkfield($table,$data);
            }
        }
    
        //检测字段属性
        public function checkfield($table,$data){
            if(!empty($table)&&!empty($data)){
                $fields=$this->getFields($table);
    
                foreach ($data as $key=>$value){
                    //检测lob字段
                    if(strtolower($fields[strtolower($key)]['type'])=='clob')  $lob[]=$key;
                    //检测PK字段并获取SEQ
                    if(strtolower($fields[strtolower($key)]['primary'])==1){
                        $this->seqname=$value;
                        $this->data[$key]=$this->getseq();//根据自动填充主键值
                        $pk=$key;//主键被设置标志
                    }
                }
                $this->lob=$lob;
                //如果没有在DATA中的设置主键值,则根据SEQNAME自动填充
                if(!isset($pk)&&!empty($this->seqname)) {
                    $this->data[$fields['pk']]=$this->getseq();
                }
                unset($lob);
                unset($pk);
            }
    
        }
    
        /**
        +----------------------------------------------------------
        * 连接ORACLE
        +----------------------------------------------------------
        */
        public function db_connect(){
            $db_pwd = C('ENCRYPT_KEY')?_decrypt(C('DB_PWD'), C('ENCRYPT_KEY')):C('DB_PWD');
            $this->conn = oci_connect(C('DB_USER'), $db_pwd, C('DB_HOST').':'.C('DB_PORT').'/'.C('DB_NAME'), C('DB_CHARSET'));
            return $this->conn;
        }
    
        /**
        +----------------------------------------------------------
        * 设置ORACLE字符集
        +----------------------------------------------------------
        */
        public function charset($code='UTF8'){
            $sql="ALTER DATABASE CHARACTER SET $code";
            $stmt = oci_parse($this->conn, $sql);
            oci_execute($stmt);
            oci_commit($this->conn);
            // Free resources
            oci_free_statement($stmt);
        }
        /**
        +----------------------------------------------------------
        * 添加包含有CLOB字段的记录
        +----------------------------------------------------------
        */
        public function insert (){
    
            //检测字段属性
            if(empty($this->lob)) $this->checkfield($this->table,$this->data);
            //字段整理
            $f=strtoupper(join(',',array_keys($this->data)));
            //数据整理
            foreach ($this->data as $key=>$val){
                $f_v_arr[]=!in_array($key,$this->lob)?"'".$val."'":"EMPTY_CLOB()";
            }
            $f_v=join(',',$f_v_arr);
    
            //lob字段清理并赋值LOB数据到绑定变量
            for ($i=0;$i<count($this->lob);$i++){
                $lob_str.=":".$this->lob[$i]."_loc,";
            }
            $returning_str.="  RETURNING ".join(',',$this->lob)." INTO ".rtrim($lob_str,',');
    
            //组装SQL
            $sql = "INSERT INTO  $this->table ($f) VALUES(".$f_v.")".$returning_str ;
    
            $stmt = oci_parse($this->conn, $sql);
    
            for ($i=0;$i<count($this->lob);$i++){
                // 创建一个“空”的OCI LOB对象绑定到定位器
                $$this->lob[$i] = oci_new_descriptor($this->conn, OCI_D_LOB);
                $lob_str=":".$this->lob[$i]."_loc";
                // 将Oracle LOB定位器绑定到PHP LOB对象
                oci_bind_by_name($stmt, $lob_str, $$this->lob[$i], -1, OCI_B_CLOB);
            }
            // 执行该语句的使用,oci_default -作为一个事务
            oci_execute($stmt, OCI_DEFAULT)    or die ("Unable to execute query
    ");
            // 保存LOB对象数据
            for ($i=0;$i<count($this->lob);$i++){
                if(!$$this->lob[$i]->save($this->data[$this->lob[$i]])){
                    $result=false;
                    break;
                }
            }
            if ( isset($result)&&$result==false ) {
                // 如果错误,则回滚事务
                oci_rollback($this->conn);
                $ret=false;
            } else {
                // 如果成功,则提交
                oci_commit($this->conn);
                $ret=true;
            }
            // 释放资源
            oci_free_statement($stmt);
            for ($i=0;$i<count($this->lob);$i++){
                $$this->lob[$i]->free();
            }
    
            return $ret;
        }
    
        /**
        +----------------------------------------------------------
        * 更新CLOB字段的内容
        +----------------------------------------------------------
        */
        public function update(){
            //检测字段属性
            if(empty($this->lob)) $this->checkfield($this->table,$this->data);
    
            //数据整理
            foreach ($this->data as $key=>$val){
                $set_arr[]=!in_array($key,$this->lob)?strtoupper($key)."='".$val."'":$key."=EMPTY_CLOB()";
            }
            $set_str=join(',',$set_arr);
    
            //lob字段清理并赋值LOB数据到绑定变量
    
            for ($i=0;$i<count($this->lob);$i++){
                $lob_str.=":".$this->lob[$i]."_loc,";
            }
    
            $returning_str.=" RETURNING ".join(',',$this->lob)." INTO ".rtrim($lob_str,',');
            $where_str=strtoupper($this->where);
            //组装SQL
            $sql = "UPDATE $this->table SET $set_str WHERE $where_str ".$returning_str;
    
            $stmt = oci_parse($this->conn, $sql);
            for ($i=0;$i<count($this->lob);$i++){
                // 创建一个“空”的OCI LOB对象绑定到定位器
                $$this->lob[$i] = oci_new_descriptor($this->conn, OCI_D_LOB);
                $lob_str=":".$this->lob[$i]."_loc";
                // 将Oracle LOB定位器绑定到PHP LOB对象
                oci_bind_by_name($stmt, $lob_str, $$this->lob[$i], -1, OCI_B_CLOB);
            }
    
            // 执行该语句的使用,oci_default -作为一个事务
            oci_execute($stmt, OCI_DEFAULT)  or die("Unable to execute query
    ");
    
            // 保存LOB对象数据
            for ($i=0;$i<count($this->lob);$i++){
                if(!$$this->lob[$i]->save($this->data[$this->lob[$i]])){
                    $result=false;
                    break;
                }
            }
            if ( isset($result)&&$result==false ) {
    
                OCIRollback($this->conn);
                $ret=false;
    
            }else $ret=true;
    
            // 提交事务
            oci_commit($this->conn);
            //释放资源
            for ($i=0;$i<count($this->lob);$i++){
                $$this->lob[$i]->free();
            }
            OCIFreeStatement($stmt);
    
            return $ret;
        }
        public function getseq(){
            $sql="select $this->seqname.nextval from dual";
    
            $stmt = oci_parse($this->conn, strtoupper($sql));
            oci_execute($stmt);
    
            while ( $row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_LOBS) ) {
                $data[]=$row;
            }
            // 释放资源
            oci_free_statement($stmt);
    
            return $data['0']['NEXTVAL'];
        }
    
        /**
        +----------------------------------------------------------
        * 查询包含有CLOB字段的记录
        +----------------------------------------------------------
        */
        public function select ($sql=''){
            $sql = empty($sql)?"SELECT * FROM  $this->table  WHERE $this->where ":$sql;
    
            $stmt = oci_parse($this->conn, strtoupper($sql));
            oci_execute($stmt);
    
            while ( $row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_LOBS) ) {
                $data[]=$row;
            }
            // 释放资源
            oci_free_statement($stmt);
            return $data;
        }
    
         /**
        +----------------------------------------------------------
        * 查询包含有CLOB字段的记录
        +----------------------------------------------------------
        */
        public function row ($sql=''){
            $sql = empty($sql)?"SELECT * FROM  $this->table  WHERE $this->where ":$sql;
    
            $stmt = oci_parse($this->conn, strtoupper($sql));
            oci_execute($stmt);
            $row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_LOBS);
            // 释放资源
            oci_free_statement($stmt);
            return $row;
        }
    
        /**
         * 取得数据表的字段信息
         * @access public
         */
         public function getFields($tableName) {
              $sql="select a.column_name,data_type,decode(nullable,'Y',0,1) notnull,data_default,decode(a.column_name,b.column_name,1,0) pk "
                      ."from user_tab_columns a,(select column_name from user_constraints c,user_cons_columns col "
              ."where c.constraint_name=col.constraint_name and c.constraint_type='P'and c.table_name='".strtoupper($tableName)
              ."') b where table_name='".strtoupper($tableName)."' and a.column_name=b.column_name(+)";
    
            $result=  $this->select($sql);
    
            $info   =   array();
            if($result) {
                foreach ($result as $key => $val) {
                    $info[strtolower($val['COLUMN_NAME'])] = array(
                        'name'    => strtolower($val['COLUMN_NAME']),
                        'type'    => strtolower($val['DATA_TYPE']),
                        'notnull' => $val['NOTNULL'],
                        'default' => $val['DATA_DEFAULT'],
                        'primary' => $val['PK'],
                        'autoinc' => $val['PK'],
                    );
                    if($val['PK']==1) $info['pk']=$val['COLUMN_NAME'];
                }
            }
            return $info;
        }
    
    
    
    }
  • 相关阅读:
    旋转数组的最小数字(JAVA)
    两个队列实现栈&两个栈实现队列(JAVA)
    重建二叉树(JAVA)
    二维数组的查找(JAVA)
    Java垃圾回收机制概述
    前端开发环境
    Java语法糖 : try-with-resources
    立个Flag (20180617-20181231)
    关于标签的整理
    Java反射机制
  • 原文地址:https://www.cnblogs.com/jiafeimao-dabai/p/11556912.html
Copyright © 2020-2023  润新知