加载中…
个人资料
永远的大头
永远的大头
  • 博客等级:
  • 博客积分:0
  • 博客访问:24,860
  • 关注人气:9
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

ThinkPHP执行ORACLE存储过程(包含CLOB参数)

(2014-12-16 21:20:35)
标签:

杂谈

ThinkPHP作为国产的框架,按造SSH的思路来架构。所以学起来还是很简单的,而且功能还很强大。作为快速开发,还是值得推荐的。
 只不过TP对ORACLE的支持并不是很强大,比如说对CLOB的支持。这里比较死版的给增加下执行存储过程的支持。
第一步,ThinkPHP/Lib/Core/Model.class.php,在execute方法下面,参照该方法,加一个execProcedure方法。
    
    public function execProcedure($sql,$parr,$parse=false) {  
        if(!is_bool($parse) && !is_array($parse)) {
            $parse = func_get_args();
            array_shift($parse);
        }
        $sql  =   $this->parseSql($sql,$parse);  
        return $this->db->execProcedure($sql,$parr);  
   
第二步,ThinkPHP/Extend/Driver/Db/DbOracle.class.php,在execute方法下面增加如下方法。
    public function execProcedure($pName,$pValue) {
        $pValue = array_change_key_case($pValue, CASE_LOWER);
        
        //释放前次的查询结果
        if ( $this->queryID ) $this->free();
        
        //启动事务,开始过程处理
        if(false === $this->startTrans()){
            $this->error();
            return FALSE;
        }
        
        N('db_write',1);
        // 记录开始执行时间
        G('queryStartTime'); 
        
        //开始组存储过程执行语句
        $argSql = "SELECT ARGUMENT_NAME,IN_OUT,DATA_TYPE FROM All_ARGUMENTS WHERE OBJECT_NAME = '".strtoupper($pName)."' ORDER BY SEQUENCE";
        $argRow = $this->query($argSql);
        $ParStr = '';
        foreach($argRow as $key=>$item){
           $ParStr .= ",:".$item['argument_name'];
        }
        $ParStr = ltrim($ParStr,',');
        $this->queryID = oci_parse($this->_linkID, 'BEGIN '.$pName.'('.$ParStr.');END;');
        
        //开始绑定存储过程参数
        foreach($argRow as $key=>$value){
            $parmName = strtolower($value['argument_name']);
            $parmType = strtolower($value['in_out']);
            $dataType = strtolower($value['data_type']);
            
            if(!isset($pValue[$parmName]['value'])){
                $pValue[$parmName]['value']='';
            }
            if(!isset($pValue[$parmName]['type'])){
                $pValue[$parmName]['type'] = SQLT_CHR;
            }
            if(!isset($pValue[$parmName]['length'])){
                $pValue[$parmName]['length']= -1;
            }            
            if($dataType === 'clob'){
                $clobTemp = $pValue[$parmName]['value'];
                $pValue[$parmName]['value'] = oci_new_descriptor($this->_linkID, OCI_D_LOB);;
                $pValue[$parmName]['type'] = OCI_B_CLOB;
                $pValue[$parmName]['length']= -1;
            }
                        
            if($parmType === 'in'){                
                oci_bind_by_name($this->queryID, ":".$parmName, $pValue[$parmName]['value'],$pValue[$parmName]['length'],$pValue[$parmName]['type']);
            }else{
                $OutData[$parmName] = $pValue[$parmName]['value'];
                oci_bind_by_name($this->queryID, ":".$parmName, $OutData[$parmName],$pValue[$parmName]['length'],$pValue[$parmName]['type']);
                if($dataType === 'clob'){
                    $OutData[$parmName]->WriteTemporary($clobTemp);
                }
            }
        }
        oci_execute($this->queryID,$this->mode);
        $this->debug();
        if (!$this->queryID) {
            $this->error();
            $this->rollback();
            return $this->queryID;
        }else {
            foreach($argRow as $key=>$value){
                $parmName = strtolower($value['argument_name']);
                $parmType = strtolower($value['in_out']);
                $dataType = strtolower($value['data_type']);
                if($dataType === 'clob' && isset($OutData[$parmName])){
                    $resultTemp = $OutData[$parmName]->load();
                    $OutData[$parmName]->free();
                    $OutData[$parmName] = $resultTemp;
                }
            }
            $this->commit();
            $this->free();
            return $OutData;
        }
    }
说明:主要用到的OCI-LIB的几个方法
$pValue[$parmName]['value'] = oci_new_descriptor($this->_linkID, OCI_D_LOB); --创建一个CLOB空对象
$OutData[$parmName]->WriteTemporary($clobTemp);--将字段字写入到CLOB对象
$resultTemp = $OutData[$parmName]->load(); --将CLOB对象内容读取出来
注意:可以看到,这里用了事务方法。主要是因为TP默认是使用OCI_COMMIT_ON_SUCCESS方式来执行sql操作,在操作完成自动提交,为防止存储过程被提前commit了,使用事务主要是将sql操作模式改为OCI_DEFAULT,手动提交。(这个是在官方文档中查到的说明,也许不是必要的)
如上,就这么简简单单,搞定了。

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有