熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

Oracle PHP 故障診斷常見問題以及解答

2013-11-13 22:23:33  來源: Oracle 

  主題
  Oracle 沒有安裝或沒有找到
  在啟動 Apache 之前在 shell 或環境中設置所有的 Oracle 環境變量
  與數據庫連接
  回顯 SQL 語句以檢查它們是否得到正確設計
  始終測試來自數據庫函數調用的返回代碼
  插入包含引號的字符串
  在 PHP 中使用 Oracle 賦值變量
  上載 LOBS
  PHP 中的數組獲取
  PEAR DB 中的 Oracle 錯誤消息
  OCI 線程安全
  使用 AS SYSDBA 或 AS SYSOPER 進行連接
  PHP 中的 NCHAR 和 NCLOB 支持
  
  
  
  Oracle 沒有安裝或沒有找到
  
  如果在 PHP 中啟用了 Oracle 支持但未能找到 Oracle 客戶端資料庫那麼當您試圖啟動 Apache 時將得到一個錯誤例如在 Windows 上如果 phpini 有 extension=php_ocidll但未能找到 Oracle 主頁則一條警告 The dynamic link library OCIdll could not be found in the specified path 將被顯示出來
  
  在啟動 Apache 之前確保 Oracle 環境變量被正確設置(參見下一主題)此外請參考由 Rob Clevenger 提供的 OTN 文章 在 Windows /XP 上安裝 OraclePHP 和 Apache
  
  Linux 用戶可能看到一個關於不能加載 libclntshso 的 Apache 錯誤但更可能在之前編譯 PHP 時注意到這個問題編譯器將以一個錯誤 Cannot find file ocidfnhCannot find file ocih 而失敗
  
  確保 Oracle 目錄對編譯 PHP 的 OS 用戶是可讀的如果您安裝了 Oracle但丟失了 Oracle 頭文件請執行一次 Oracle 的 Client 安裝Client 安裝指的是 Oraclei Database Release 安裝器中那個名稱的選項(給出的其它三個選項是 DatabaseManagement and Integration和 Cluster Management)此外還請參考 OTN 文章在 Linux 上安裝 OraclePHP 和 Apache
  
  
  
  在啟動 Apache 之前在 shell 或環境中設置所有的 Oracle 環境變量
  
  在 Apache 啟動之前設置所有的 Oracle 環境變量是使 PHP 能夠與 Oracle 通信的一種安全的方法在 PHP 腳本或 文件中設置變量通常不起作用由於通常對環境的混淆存在許多郵件列表和論壇帖子在 Windows 和 Linux 上的行為也不同
  
  OTN 文章 在 Linux 上安裝 OraclePHP 和 Apache 給出了一個名為 start_apache用來設置環境和啟動 Apache 的例子
  
     #!/bin/sh
     ORACLE_HOME=/u/app/oracle/product/
  
     ORACLE_SID=orcl
     export ORACLE_HOME ORACLE_SID
     echo Oracle Home: $ORACLE_HOME
     echo Oracle SID: $ORACLE_SID
     echo Starting Apache
     /apachectl start
  
  我做了一些測試來查看該環境對 PHP 調用有什麼影響
  
     $mycon = OCILogon(myusername mypassword MYDB);
  
  我用了 RedHat Linux AS Apache 和 PHP
  
  在 apachectl start 之前沒有設置 ORACLE_HOME 並且在 PHP 腳本中沒有 putenv(ORACLE_HOME=/usr/oracle/MYDB) 的情況下我得到
  
  Warning:ocilogon():_oci_open_server:
  Error while trying to retrieve text for error ORA
  
  這顯示連接失敗未能找到消息文件(這些文件位於 Oracle 主目錄下)
  
  在 PHP 腳本中有 putenv(ORACLE_HOME=/usr/oracle/MYDB)但沒有設置 ORACLE_HOME 的情況下我得到
  
  Warning:ocilogon():_oci_open_server:
  ORA:TNS:could not resolve service name
  
  連接仍然沒有成功但在錯誤出現之後能夠從消息文件中讀出消息正文
  
  在 apachectl start 之前設置了 ORACLE_HOME 但沒有 putenv() 的情況下連接成功了這是推薦的配置
  
  在 apachectl start 之前正確設置 ORACLE_HOME 同時 putenv() 使用一個無效 ORACLE_HOME 目錄的情況下連接成功我也在 Windows 上試驗了這種情況這次連接失敗了出現和我上面的第一次測試同樣的消息
  
  當我用一條 Apache 指令 setenv ORACLE_HOME /usr/oracle/MYDB 來替換 PHP putenv() 調用時得到了一組類似的結果
  
  一些變量可以在 PHP 腳本中設置在啟動 Apache 之前正確設置 ORACLE_HOME 之後以下操作改變了我的默認連接並連接到 MYDB
  
  putenv(TWO_TASK=MYDB);
  $mycon = OCILogon(myusername mypassword);
  
  環境變量 TNS_ADMINNLS_DATE_FORMAT(可能還有其它變量)也可以用這種方式來設置
  
  
  
  與數據庫連接
  
  用戶選擇的網絡服務名稱常常用來識別要與哪個數據庫連接它被默認從環境變量 ORACLE_SID 中讀出或者它可以在連接調用中顯式地給出網絡服務名稱 MYDB 可以用在 Oracle 的命令行 SQL*Plus 實用程序中
  
  sqlplus myusername/mypassword@MYDB
  
  
  或用在 PHP 中
  
  $mycon = OCILogon(myusername mypassword MYDB);
  
  網絡服務名稱通常通過 tnsnamesora 文件中的一個項目映射到一個實際的數據庫上
  
     MYDB =
      (DESCRIPTION =
       (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = TCP)(HOST = mymachinemydomain)(PORT = ))
       )
       (CONNECT_DATA =
        (SERVER = DEDICATED)
        (SERVICE_NAME = MYDBmydomain)
       )
      )
  
  $ORACLE_HOME/network/admin/tnsnamesora 文件被默認使用在一些操作系統上如果默認文件不存在則將檢查其它的位置
  
  如果在 tnsnamesora 中找不到被用在 OCILogon() 中的網絡服務名稱或者 PHP 根本沒找到 tnsnamesora那麼您在登錄時可能得到一個錯誤
  
  Warning:ocilogon():_oci_open_server:ORA:TNS:could not resolve service name
  
  在啟動 Apache web server 之前檢查環境變量 ORACLE_HOME 是否正確設置(參見之前的主題)
  
  如果您的 tnsnamesora 在一個非默認的位置您可以將環境變量 TNS_ADMIN 設置為包含它的目錄例如如果您在使用 /tmp/tnsnamesora將這些行添加到 start_apache 中(同樣參見之前的主題)
  
  TNS_ADMIN=/tmp
  export TNS_ADMIN
  
  另一種解決辦法是在 OCILogon() 調用中使用完整的連接字符串
  
     $db = (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)
            (HOST = mymachinemydomain)(PORT=)))
            (CONNECT_DATA=(SERVER=DEDICATED)
            (SERVICE_NAME=MYDBmydomain)));
  
     $mycon = OCILogon(myusername mypassword $db);
     
  
  如果 $ORACLE_HOME/network/admin/sqlnetora 與 tnsnamesora 不同步且一個域名被隱式地添加到了別名中那麼錯誤 ORA 也可能發生OCILogon() 調用中的不合格網絡服務名稱將添加 sqlnetora 的 NAMESDEFAULT_DOMAIN 值例如如果 sqlnetora 有
  
  NAMESDEFAULT_DOMAIN =
  
  那麼 OCILogon(myusername mypassword mydb) 將使 Oracle 在 tnsnamesora 中尋找別名 MYDBAUORACLECOM = 一種快速的解決辦法是將 tnsnamesora 項目改變為
  
      MYDBAUORACLECOM =
       (DESCRIPTION =
        (ADDRESS_LIST =
         (ADDRESS = (PROTOCOL = TCP)(HOST = mymachinemydomain)(PORT = ))
        )
        (CONNECT_DATA =
         (SERVER = DEDICATED)
         (SERVICE_NAME = MYDBmydomain)
        )
       )
  
  
  
  回顯 SQL 語句檢查它們是否得到正確設計
  
  令人意外的是沒有得到結果或者得到錯誤的結果常常歸因於執行了錯誤的語句在開發期間從 PHP 回顯每一條完整的 SQL 語句檢查它是否得到正確設計所有變量是否得到了正確擴展引用錯誤或者對字符串中 PHP 的變量語法的錯誤理解可能導致不正確的語句被執行
  
  在執行它們之前測試 SQL*Plus 中的 SQL 語句也有助於確認正確性
  
  當語句被輸入到諸如 SQL*Plus 之類的工具中時通常用一個分號來告訴工具這個語句完成了現在可以被執行不過分號不被認為是語句的一部分並且不會被發送到數據庫中在 PHP 中不要向 SQL 語句中添加分號否則將出現一個 Oracle 錯誤這個例子是一次有效的查詢
  
  
  $sql =
From:http://tw.wingwit.com/Article/program/Oracle/201311/18973.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.