• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    Thinkphp與Oracle之間的各種問題

    來源:懂視網 責編:小采 時間:2020-11-09 13:02:06
    文檔

    Thinkphp與Oracle之間的各種問題

    Thinkphp與Oracle之間的各種問題:Thinkphp對Oracle的支持簡直弱爆,只做到了基本的操作,就連事務都不支持。今天來手動改一改DbOracle.class.php,讓它稍微好用一些吧。 首先是insert。原來的insert應該沒有什么問題,但實際項目中更多的是需要在插入的時候遇到已存在的記錄則進行更新。于是
    推薦度:
    導讀Thinkphp與Oracle之間的各種問題:Thinkphp對Oracle的支持簡直弱爆,只做到了基本的操作,就連事務都不支持。今天來手動改一改DbOracle.class.php,讓它稍微好用一些吧。 首先是insert。原來的insert應該沒有什么問題,但實際項目中更多的是需要在插入的時候遇到已存在的記錄則進行更新。于是

    Thinkphp對Oracle的支持簡直弱爆,只做到了基本的操作,就連事務都不支持。今天來手動改一改DbOracle.class.php,讓它稍微好用一些吧。 首先是insert。原來的insert應該沒有什么問題,但實際項目中更多的是需要在插入的時候遇到已存在的記錄則進行更新。于是

    Thinkphp對Oracle的支持簡直弱爆,只做到了基本的操作,就連事務都不支持。今天來手動改一改DbOracle.class.php,讓它稍微好用一些吧。

    首先是insert。原來的insert應該沒有什么問題,但實際項目中更多的是需要在插入的時候遇到已存在的記錄則進行更新。于是,利用Oracle中的MERGE INTO來實現這一點。

    public function insert($data, $options = array(), $replace = false)
    {
     if (!$replace) {
     return parent::insert($data, $options, $replace);
     }
     $values = $fields = array();
     $this->model = $options['model'];
     $sql_merge = 'MERGE INTO ' . $this->parseTable($options['table']) .
     ' using (select 1 from dual) ' .
     ' ON (' . $this->parseValue($data[$options['marge_key']]) . ' is not null and ' . $this->parseValue($data[$options['marge_key']]) . ' = ' . $options['marge_key'] . ')';
     //insert
     foreach ($data as $key => $val) {
     //主鍵值為空時,不插入主鍵
     if ($this->parseKey($key) == $this->parseKey($options['marge_key'])
     && $val == null
     ) {
     } elseif (is_array($val) && 'exp' == $val[0]) {
     $fields[] = $this->parseKey($key);
     $values[] = $val[1];
     } elseif (is_scalar($val) || is_null(($val))) { // 過濾非標量數據
     $fields[] = $this->parseKey($key);
     if (C('DB_BIND_PARAM') && 0 !== strpos($val, ':')) {
     $name = md5($key);
     $values[] = ':' . $name;
     $this->bindParam($name, $val);
     } else {
     $values[] = $this->parseValue($val);
     }
     }
     }
     $sql_insert = 'INSERT (' . implode(',', $fields) . ') VALUES (' . implode(',', $values) . ')';
     //update
     if (isset($data[$this->parseKey($options['marge_key'])])
     || $data[$this->parseKey($options['marge_key'])] == null
     ) {
     unset($data[$this->parseKey($options['marge_key'])]);
     }
     $sql_update = 'UPDATE '
     . $this->parseSet($data)
     . $this->parseWhere(!empty($options['where']) ? $options['where'] : '')
     . $this->parseOrder(!empty($options['order']) ? $options['order'] : '')
     . $this->parseLimit(!empty($options['limit']) ? $options['limit'] : '');
     $sql = $sql_merge . ' WHEN MATCHED THEN ' . $sql_update . ' WHEN NOT MATCHED THEN ' . $sql_insert;
     return $this->execute($sql, $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()));
    }
    

    不支持事務是Thinkphp連接Oracle時的另一個問題,框架作者似乎已經做過適配,但是應該是沒有測試,留下一堆bug。DbOracle.class.php中已經有了startTrans,commit,rollback等,稍作修改即可。

    Thinkphp對數據庫的所有操作最終都是匯集到query或execute上來執行,但這兩個函數里放了一句$this->mode = OCI_COMMIT_ON_SUCCESS;活生生的把事務扼殺了,所以,這里先把兩個函數里的這句注釋掉。

    然后,驚人得發現execute()中調用oci_execute時根本沒有傳入mode!前面辛辛苦苦改mode又是何苦,果斷加上oci_execute($stmt, $this->mode)。

    接下來才是讓事務生效的重頭戲。在事務的幾個開關函數中加入對mode的修改,在startTrans()中,將mode設為OCI_DEFAULT,commit和rollback中將將mode設為改回OCI_COMMIT_ON_SUCCESS。這三個函數大概就是這樣子的:

    /**
     * 啟動事務
     * @access public
     * @return void
     */
     public function startTrans() {
     $this->initConnect(true);
     if ( !$this->_linkID ) return false;
     //數據rollback 支持
     if ($this->transTimes == 0) {
     $this->mode = OCI_DEFAULT;
     }
     $this->transTimes++;
     return ;
    }
    /**
     * 用于非自動提交狀態下面的查詢提交
     * @access public
     * @return boolen
     */
    public function commit(){
     if ($this->transTimes > 0) {
     $result = oci_commit($this->_linkID);
     if(!$result){
     $this->error();
     return false;
     }
     $this->mode = OCI_COMMIT_ON_SUCCESS;//陳宣亦 2014.11.09 14:07
     $this->transTimes = 0;
     }
     return true;
    }
    /**
     * 事務回滾
     * @access public
     * @return boolen
     */
     public function rollback(){
     if ($this->transTimes > 0) {
     $result = oci_rollback($this->_linkID);
     if(!$result){
     $this->error();
     return false;
     }
     $this->mode = OCI_COMMIT_ON_SUCCESS;//陳宣亦 2014.11.09 14:07
     $this->transTimes = 0;
     }
     return true;
    }
    

    還有一個頭疼的問題就是日期類型轉換,我還在尋找一種便捷的方法來解決這個問題。以后再補充上來吧。

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    Thinkphp與Oracle之間的各種問題

    Thinkphp與Oracle之間的各種問題:Thinkphp對Oracle的支持簡直弱爆,只做到了基本的操作,就連事務都不支持。今天來手動改一改DbOracle.class.php,讓它稍微好用一些吧。 首先是insert。原來的insert應該沒有什么問題,但實際項目中更多的是需要在插入的時候遇到已存在的記錄則進行更新。于是
    推薦度:
    標簽: php 的所有 問題
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 99久久成人国产精品免费| 欧美日韩精品在线| 国产精品v欧美精品v日韩精品| 精品视频一区二区三区| 国产精品专区第二| 色一乱一伦一图一区二区精品| 精品国产AⅤ一区二区三区4区| 国产精品666| 久久精品国产亚洲AV电影| 亚洲一区精品无码| 午夜精品久久久久成人| 国产视频精品免费视频| 亚洲精品无码不卡| 99免费精品视频| 国产精品人成在线播放新网站| 亚洲AV无码久久精品狠狠爱浪潮 | 国产伦精品一区二区三区女| 四虎国产成人永久精品免费| 欧洲精品码一区二区三区免费看| 国产成人久久久精品二区三区| 精品在线免费观看| 91精品美女在线| 97久久精品国产精品青草| 国产精品免费大片| 精品国产一区二区三区色欲| 久久夜色精品国产噜噜噜亚洲AV| 亚洲AV第一页国产精品| 亚洲国产精品VA在线看黑人| 亚洲无码精品浪潮| 综合人妻久久一区二区精品| 欧美激情精品久久久久久久九九九| 久久996热精品xxxx| 国产欧美精品一区二区三区四区 | 久久永久免费人妻精品下载| 精品性影院一区二区三区内射| 精品无码人妻一区二区三区品 | 国产精品三级在线| 99久久精品费精品国产一区二区| 国产91精品一区二区麻豆网站| 国产成人精品亚洲日本在线| 精品精品国产自在久久高清|