【PHP+Oracle+CLOB】PHP处理Oracle中大文本CLOB数据的问题?

本文介绍了一个用于处理Oracle数据库中CLOB字段和MySQL中TEXT类型字段的PHP类,详细展示了如何在PHP中实现对这两种字段类型的插入、更新、查询及计数等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MySQL中text类型与Oracle中的CLOB对应

<?php
class OciModel
{
    public  $conn;
    public  $table;
    public  $seqname;
    public  $where;//查询条件,字符串
    public  $lob;//lob字段名,数组
    public  $data;//数据数组

    //架构函数
    public function __construct($table='',$data=''){
        //取TP框架的数据库配置
        $this->connect('database.username','database.password','database.hostname'.':'.'database.hostport'.'/'.'database.database');

        if(!empty($table))
            $this->table=$table;
        if(!empty($table)&&!empty($data)){
            $this->checkfield($table,$data);
        }
    }

    //检测字段属性
    public function checkfield($table,$data){
        $lob = null;
        if(!empty($table)&&!empty($data)){
            $fields=$this->getFields($table);
            //print_r($fields);exit;
            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 connect($user, $password, $SID){
        // 创建连接,并设置字符编码为'UTF8'.
        $this->conn = oci_connect ($user, $password, $SID, 'UTF8');
    }

    /**
    +----------------------------------------------------------
     * 设置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)));
        //数据整理
        $f_v_arr = array();
        foreach ($this->data as $key=>$val){
            if(is_object($val)&&get_class($val)=='think\db\Expression'){
                $f_v_arr[]=$val;
            }else
                $f_v_arr[]=!in_array($key,$this->lob)?"'".$val."'":"EMPTY_CLOB()";
        }
        $f_v=join(',',$f_v_arr);

        //lob字段清理并赋值LOB数据到绑定变量
        $lob_str = '';
        $returning_str = '';

        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);

        $objList=[];
        for ($i=0;$i<count($this->lob);$i++){
            // 创建一个“空”的OCI LOB对象绑定到定位器
            $objList[$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, $objList[$i], -1, OCI_B_CLOB);

        }
	
        // 执行该语句的使用,oci_default -作为一个事务
        oci_execute($stmt, OCI_NO_AUTO_COMMIT) or die ("Unable to execute query\n");

        // 保存LOB对象数据
        for ($i=0;$i<count($this->lob);$i++){
            if(!$objList[$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++){
            $objList[$i]->free();
        }

        return $ret;

    }

    /**
    +----------------------------------------------------------
     * 更新CLOB字段的内容
    +----------------------------------------------------------
     */
    public function update(){
        //检测字段属性
        if(empty($this->lob)) $this->checkfield($this->table,$this->data);

        $set_arr = array();
        //数据整理
        foreach ($this->data as $key=>$val){
            if(is_object($val)&&get_class($val)=='think\db\Expression'){
                $set_arr[]=strtoupper($key)."=".$val."";
            }else
                $set_arr[]=!in_array($key,$this->lob)?strtoupper($key)."='".$val."'":$key."=EMPTY_CLOB()";
        }
        $set_str=join(',',$set_arr);

        //lob字段清理并赋值LOB数据到绑定变量
        $lob_str = '';
        $returning_str = '';

        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);

        $objList=[];
        for ($i=0;$i<count($this->lob);$i++){
            // 创建一个“空”的OCI LOB对象绑定到定位器
            $objList[$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, $objList[$i], -1, OCI_B_CLOB);
        }

        // 执行该语句的使用,oci_default -作为一个事务
        oci_execute($stmt, OCI_DEFAULT) or die ("Unable to execute query\n");

        // 保存LOB对象数据
        for ($i=0;$i<count($this->lob);$i++){
            if(!$objList[$i]->save($this->data[$this->lob[$i]])){
                $result=false;
                break;
            }
        }
        if ( isset($result)&&$result==false ) {
            oci_rollback($this->conn);
            $ret=false;

        }else $ret=true;

        // 提交事务
        oci_commit($this->conn);
        //释放资源
        for ($i=0;$i<count($this->lob);$i++){
            $objList[$i]->free();
        }
        oci_free_statement($stmt);
        return $ret;
    }

    public function getseq(){
        $sql="select $this->seqname.currval from dual";

        $stmt = oci_parse($this->conn, strtoupper($sql));

        oci_execute($stmt);
        $data = array();
        while ( $row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_LOBS) ) {
            if($row == null) continue;
            array_push($data, $row);
        }
        // 释放资源
        oci_free_statement($stmt);
        array_filter($data);
        return $data[0]['CURRVAL'];
    }

    /**
    +----------------------------------------------------------
     * 查询包含有CLOB字段的记录
    +----------------------------------------------------------
     */
    public function select($sql='',$find = false){
        $sql = empty($sql) ? "SELECT * FROM  $this->table  WHERE $this->where ":$sql;

        $stmt = oci_parse($this->conn, strtoupper($sql));

        oci_execute($stmt);
        $data = array();
        while ( $row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_LOBS) ) {
            $data[]=$row;
        }
        // 释放资源
        oci_free_statement($stmt);

        return $data ? ( $find ? $data[0] : $data ) : $data;
    }

    /**
    +----------------------------------------------------------
     * 查询包含有CLOB字段的记录
    +----------------------------------------------------------
     */
    public function count($sql=''){
        $sql = empty($sql) ? "SELECT count(*) FROM  $this->table  WHERE $this->where ":$sql;
        $stmt = oci_parse($this->conn, strtoupper($sql));
        oci_execute($stmt);
        $row = oci_fetch_row($stmt);
        // 释放资源
        oci_free_statement($stmt);
        return $row?$row[0]:0;
    }

    /**
     * 取得数据表的字段信息
     * @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' => isset($val['DATA_DEFAULT'])?$val['DATA_DEFAULT']:null,
                    'primary' => $val['PK'],
                    'autoinc' => $val['PK'],
                );
                if($val['PK']==1) $info['pk']=$val['COLUMN_NAME'];
            }
        }
        return $info;
    }
}

使用封装的类进行数据操作。
使用说明:

新增:

$data['a'] = 'a';
$data['b'] = 'b';
$model = new OciModel( '表名' );
$model->data = $data;
return $model->insert();

编辑:
$data['a'] = 'a';
$data['b'] = 'b';
$model = new OciModel( '表名' );
$model->data = $data;
$model->where = 'id = 123';
return $model->update();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值