2011-12-21 19 views
10

Tôi đã học được rằng odbc_execute() không phải lúc nào cũng kích hoạt lỗi ODBC đúng khi trả về FALSE (không ít nhất với trình điều khiển Oracle) và tôi không thể tin tưởng hoàn toàn odbc_error() hoặc odbc_errormsg(). Tình huống này dễ phát hiện khi không có lỗi trước đó vì odbc_error() trả về một chuỗi trống. Tuy nhiên, khi nó trả về một cái gì đó tôi không biết liệu nó thuộc về hoạt động thất bại cuối cùng hay nó vẫn còn sót lại từ một lỗi trước đó.Lừa để đặt lại odbc_error()

Giải pháp đơn giản nhất sẽ được thiết lập lại các odbc_error()odbc_errormsg() chức năng khi xảy ra lỗi trong các cuộc gọi để tiếp theo sẽ bắt đầu từ đầu, nhưng tôi không thể tìm thấy một cách hỗ trợ để làm như vậy. Bạn có thể tìm ra cách để làm điều đó không?

Thông tin cơ bản: Tôi đang nâng cấp ứng dụng cũ với lớp bao gồm các cuộc gọi cơ sở dữ liệu. Đó là lý do tại sao tôi cần phải làm mọi thứ càng chung chung càng tốt.

Trả lời

1

odbc_error đôi khi trở nên khó hiểu. chuỗi sql được thực hiện và thông báo lỗi có thể khác nhau. Để ngăn chặn điều này, chúng ta có thể giữ tất cả các sqls được thực hiện trong một mảng, và sau khi tất cả các thực thi kết thúc, chúng ta có thể kiểm tra các thông báo lỗi là gì.

Đầu tiên chúng ta hãy định nghĩa một lớp executedSQL mà sẽ giữ các thông tin SQLs thực hiện:

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

Lớp này sẽ giữ tất cả thông tin sql và kết quả của họ và trở về tin nhắn.

Nếu chúng ta sử dụng một lớp để kết nối db 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; 
    } 
} 

Nếu chúng ta thực hiện SQLs của chúng tôi:

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

Điều này sẽ in tất cả SQLs và kết quả của họ. Tại thời điểm này chúng ta có thể thấy sql đã thực hiện và thông báo lỗi liên quan của nó. Vì vậy, theo nghĩa đen chúng tôi không đặt lại odbc_error nhưng chúng tôi làm cho nó rõ ràng hơn. Nếu một thông báo lỗi lặp đi lặp lại hai lần, nó có thể được đẩy hơn là nó thuộc về sql được thực thi trước đó. Cách gỡ lỗi này trở nên dễ dàng hơn.

+0

Cảm ơn câu trả lời của bạn. Tuy nhiên, câu trả lời của bạn chỉ là tốt cho trường hợp mà một trong những nhu cầu thông báo lỗi cho mục đích gỡ lỗi chỉ. Trong một ứng dụng thế giới thực, người ta có thể dựa vào các thông báo lỗi để đưa ra quyết định (hành vi khác nhau theo lỗi, hoặc dịch tin nhắn theo cách có ý nghĩa đối với người dùng cuối). Đây là lý do tại sao tôi cần một câu trả lời kỹ lưỡng và cung cấp một tiền thưởng. –

+0

Lỗi nền tảng gốc mà câu hỏi này nói đến là 'odbc_errormsg()' có thể trả lời thư một cách vui vẻ từ một câu lệnh trước. Vấn đề không phải là để phát hiện xem truy vấn của bạn thành công (đó là dễ dàng), vấn đề là để đảm bảo rằng các thông báo lỗi không thuộc về một truy vấn trước đó.Trừ khi tôi đang thiếu một cái gì đó, mã của bạn không có gì để giải quyết điều đó. –

+0

Trong phương pháp này, chúng ta có thể phát hiện xem có một thông điệp arror từ câu lệnh trước đó hay không. Ví dụ, chúng ta đang thực hiện ba truy vấn. Đầu tiên là thành công, thứ hai thất bại và trả về "thất bại tin nhắn 1". Và thứ ba cũng không trả về "thất bại tin nhắn 1". Bằng cách tiếp cận này, chúng ta có thể biết rằng "thông báo lỗi 1" thuộc về truy vấn 2. – isa

2

nó không necesary để thiết lập lại chức năng tôi giải quyết theo cách này:

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

Nếu bạn quyết định bắt ngoại lệ và bỏ qua lỗi (ví dụ: bởi vì đó là khóa trùng lặp mà logic mã của bạn có thể xử lý), thông báo lỗi của nó có thể kết thúc với các lỗi tiếp theo. Đó là những gì tôi muốn bảo vệ chống lại. –

+0

'$ this-> catchException()' làm gì? –

+0

chức năng công khai catchException ($ odbc_errormsg) { // echo "Funciona en catch
"; $ patron_error = "/ SQL \ d + /"; nếu (preg_match ($ patron_error, $ odbc_errormsg, $ coincidencias)) { ném ngoại lệ mới ($ coincidencias [0]. ";". $ Odbc_errormsg); } } Hiện tại, nó chỉ hữu ích với các thông báo lỗi của DB2. Tôi hy vọng tìm ra cách để quản lý lỗi của một cơ sở dữ liệu khác với trình điều khiển php odbc – vteran93

0

lỗi odbc_errormsg không thể được thiết lập lại trong kịch bản. Vì vậy, thực sự là một cách dễ dàng để tách các lỗi odbc_errormsg là gán mỗi obdc_connect một mã định danh duy nhất. Ví dụ hiển thị $ db = @ odbc_connect ($ somefile, ......) nhưng sử dụng tên ngẫu nhiên hoặc duy nhất => $ db900 = @ odbc_connect ($ somefile, ......) hoặc $ myuniquename = @ odbc_connect ($ somefile, ......) sẽ phân tách các thông báo lỗi. Sau đó sử dụng odbc_errormsg ($ myuniquename) sẽ chỉ trả về lỗi cho id đó.

Các vấn đề liên quan