2011-12-21 30 views
10

我瞭解到,odbc_execute()並不總是觸發一個適當的ODBC錯誤,當它返回FALSE(至少不與Oracle驅動程序),我不能完全信任odbc_error()odbc_errormsg()。當沒有先前的錯誤時,這種情況很容易檢測,因爲odbc_error()返回空字符串。但是,當它返回一些內容時,我不知道它是屬於上次失敗的操作,還是來自先前的錯誤。伎倆復位odbc_error()

最簡單的解決辦法是重置odbc_error()odbc_errormsg()功能,當有一個錯誤,以便下一次調用將從頭開始,但我無法找到一個支持的方式這樣做。你能想出辦法嗎?

背景:我正在使用封裝數據庫調用的類來增強傳統應用程序。這就是爲什麼我需要儘可能通用。

回答

1

odbc_error有時會變得混亂。執行的sql字符串和錯誤信息可能會有所不同。爲了防止這種情況,我們可以將所有執行的sqls保存在一個數組中,並且在所有執行完成後,我們可以檢查錯誤消息是什麼。

首先我們定義一個executedSQL類將舉行的執行sql語句的信息:

class executedSQL 
{ 
    public sql; 
    public result; 
    public error; 
    public message; 
} 

這個類將持有的所有SQL信息及其結果,並返回的消息。

如果我們使用一個類來連接ODBC數據庫:

class myODBC 
{ 
    //holds the connection 
    public $connection; 

    //all executed sql string are added to this array as executedSQL object. 
    public $executedSQLs = array(); 


    public function connect() 
    { 
     $this->connection = dbc_connect(" ", " ","") or die(odbc_errormsg()); 
    } 

    public function execute($sql) 
    { 
     $execution = odbc_exec($this->connection, $sql); //execute it 

     //put all the results to executedSQL object 
     $executed = new executedSQL(); 
     $executed->sql = $sql; 
     $executed->result = $execution; 
     $executed->error = odbc_error(); 
     $executed->message = odbc_errormsg(); 

     //push to executedSQLs var. 
     array_push($this->executedSQLs, $executed); 

     return $execution; 
    } 
} 

如果我們執行sql語句:

$db = new myODBC(); 

$db->connect(); 

$db->execute("select * from table1"); 
$db->execute("this is gonna be failed sql"); 
$db->execute("select * from table2"); 

print_r($db->executedSQLs); 

這將打印的所有SQL及其結果。在這一點上,我們可以看到執行的SQL及其相關的錯誤消息。所以從字面上看,我們不會重置odbc_error,但我們會更加清楚。如果錯誤消息重複兩次,則更適合於它屬於之前執行的SQL。這樣調試變得更容易。

+0

感謝您的回答。然而,你的答案只適用於只爲調試目的需要錯誤消息的情況。在真實世界的應用程序中,應該能夠依靠錯誤消息來做出決定(根據錯誤採取不同的行爲,或者以對最終用戶有意義的方式來翻譯消息)。這就是爲什麼我需要一個徹底的答案,並提供賞金。 – 2014-12-12 19:57:02

+0

這個問題的根本問題在於'odbc_errormsg()'可以愉快地從前面的語句中返回消息。問題不在於檢測您的查詢是否成功(這很容易),問題是要確保錯誤消息不屬於先前的查詢。除非我錯過了一些東西,否則你的代碼無法解決這個問題。 – 2014-12-17 15:42:00

+0

在這種方法中,我們可以檢測是否來自前一個語句的錯誤消息。例如,我們正在執行三個查詢。第一個成功,第二個失敗並返回「失敗消息1」。第三個也失敗返回「失敗消息1」。通過這種方法,我們可以知道「失敗消息1」屬於查詢2. – isa 2014-12-18 11:38:29

2

它不是necesary重置我以這種方式解決了這個功能:

function foo($sql){ 
    $res = odbc_exec($this->dbconn, $sql); 
    if (odbc_error() and $res===false) { 
     return $this->catchException(odbc_errormsg($this->dbconn)); 

    } 
    return $res; 
} 
+0

如果您決定捕捉異常並忽略錯誤(例如,因爲它是您的代碼邏輯可以處理的重複鍵),它的錯誤消息可能最終會與下一個錯誤關聯。這就是我想要防範的。 – 2014-12-17 15:39:21

+0

'$ this-> catchException()'做了什麼? – 2014-12-17 16:54:26

+0

public function catchException($ odbc_errormsg){echo「Funciona en catch
」; $ patron_error =「/ SQL \ d + /」; if(preg_match($ patron_error,$ odbc_errormsg,$ coincidencias)){ throw new Exception($ coincidencias [0]。「;」。$ odbc_errormsg); } } 現在,它僅適用於DB2的錯誤消息。我希望找到一種方法來管理php odbc驅動程序中的其他數據庫的錯誤 – vteran93 2014-12-17 21:41:26

0

odbc_errormsg錯誤不能腳本時被重置。所以,實際上一個簡單的方法來分離odbc_errormsg錯誤是爲每個obdc_connect分配一個唯一的標識符。示例顯示$ db = @ odbc_connect($ somefile,......),但使用隨機或唯一名稱=> $ db900 = @ odbc_connect($ somefile,......)或$ myuniquename = @ odbc_connect $ somefile,......)將單獨顯示錯誤消息。然後使用odbc_errormsg($ myuniquename)將只返回該id的錯誤。

相關問題