2008-09-06 67 views
10

我正在處理將JobName列定義爲UNIQUE的MySQL表。如果有人試圖使用已存在於數據庫中的JobName將新Job保存到數據庫,則MySQL將引發警告。我可以使用PHP檢測並處理MySQL警告嗎?

我想能夠檢測這個警告,就像一個錯誤,在我的PHP腳本,並用它妥善處理。理想情況下,我想知道MySQL拋出了什麼樣的警告,以便我可以分支代碼來處理它。

這可能嗎?如果沒有,是因爲MySQL沒有這個能力,PHP沒有這個能力,或者兩者兼而有之?

回答

10

的警告是「標記」,以PHP本身就需要改變在MySQL/MySQLi驅動程序,這顯然超出了這個問題的範圍。相反,你將不得不基本檢查您使數據庫的警告在每次查詢:

$warningCountResult = mysql_query("SELECT @@warning_count"); 
if ($warningCountResult) { 
    $warningCount = mysql_fetch_row($warningCountResult); 
    if ($warningCount[0] > 0) { 
     //Have warnings 
     $warningDetailResult = mysql_query("SHOW WARNINGS"); 
     if ($warningDetailResult) { 
      while ($warning = mysql_fetch_assoc(warningDetailResult) { 
       //Process it 
      } 
     } 
    }//Else no warnings 
} 

顯然,這將是可怕昂貴適用EN-質量,所以你可能需要仔細想想,當以及如何產生警告(這可能導致您重構以消除它們)。

僅供參考,MySQL SHOW WARNINGS

當然,你可以用的SELECT @@warning_count,這將節省您每次執行一個查詢的初始查詢免除,但我把它的迂腐完整性。

+0

或者使用具有warning_count屬性的MySQLi驅動程序。 http://php.net/manual/en/mysqli.warning-count.php – 2011-10-19 12:33:59

4

首先,您應該turn warnings off以便您的訪客不會看到您的MySQL錯誤。其次,當你打電話給mysql_query()時,你應該檢查它是否返回錯誤。如果確實如此,請撥打mysql_errno()以查明問題所在。將返回的編號與this page上的錯誤代碼相匹配。

它看起來這是你要找的錯誤編號:

Error: 1169 SQLSTATE: 23000 (ER_DUP_UNIQUE)

Message: Can't write, because of unique constraint, to table '%s'

+5

如果我沒有記錯他詢問的警告,而不是錯誤。警告仍然允許查詢通過,因此`mysql_query`不會返回`false`。請參閱iAn對PHP有限警告支持的回答。 – Andrew 2013-12-07 20:36:09

0

更新,刪除有關錯誤號的功能,我現在認識到沒有在您的情況適用的東西...

一件事在MySQL警惕的爲UPDATE聲明:mysqli_affected_rows()將返回零,即使WHERE子句匹配的行,但SET條款實際上並沒有改變數據值。我只提到這一點,因爲這種行爲導致了我曾經看到的一個系統中的錯誤 - 程序員使用該返回值在更新後檢查錯誤,假設零表示發生了一些錯誤。這只是表示用戶在單擊更新按鈕之前沒有更改任何現有值。

所以我想用mysqli_affected_rows()也不能依靠找到這樣的警告,除非你有像表中的update_time列這樣的東西,總是會被分配一個新的時間戳值更新時。這種解決方法似乎有點kludgey雖然。

0

取決於什麼(如果有的話),你正在使用的框架,我建議你做一個查詢,以檢查作業名自己,並與驗證的表格的其餘部分創建正確的信息給用戶。

根據jobnames的數量,你可以在名稱發送到包含形式和使用JavaScript來告訴使用其所持的看法。

如果這對你沒有意義,那麼總結我的觀點是這樣的:不要設計你的程序和/或用戶試圖做非法的事情,並在他們做和處理它時捕捉錯誤。設計你的系統不會造成錯誤會更好,恕我直言。保持錯誤實際的錯誤:)

0

您可以檢測使用的mysqli語句錯誤沒有唯一鍵衝突。 mysqli語句返回錯誤1062,即ER_DUP_ENTRY。您可以查找錯誤1062並打印適當的錯誤消息。如果你想打印你的列(jobName)也作爲你的錯誤信息的一部分,那麼你應該解析語句錯誤字符串。

 
    if($stmt = $mysqli->prepare($sql)){ 
      $stmt->bind_param("sss", 
      $name, 
      $identKey, 
      $domain); 


      $stmt->execute(); 
      if($mysqli->affected_rows != 1) { 
         //This will return errorno 1062 
       trigger_error('mysql error >> '.$stmt->errno .'::' .$stmt->error, E_USER_ERROR); 
       exit(1); 
      } 
      $stmt->close(); 
     } else { 

      trigger_error('mysql error >> '. $mysqli->errno.'::'.$mysqli->error,E_USER_ERROR); 
     } 
0

有可能得到警告,並且以比mysql更高效的方式使用mysqli。

這裏使用的是人工page建議在php.net的財產mysqli-> WARNING_COUNT代碼:上抑制警告

$mysqli->query($query); 

if ($mysqli->warning_count) { 
    if ($result = $mysqli->query("SHOW WARNINGS")) { 
     $row = $result->fetch_row(); 
     printf("%s (%d): %s\n", $row[0], $row[1], $row[2]); 
     $result->close(); 
    } 
} 
0

注:一般來說,它是不以防止警告是個好主意顯示,因爲你可能會錯過重要的東西。如果你絕對必須隱藏某種原因警告,可以放置一個@標誌在聲明前做一個單獨的基礎上。這樣,您不必關閉所有警告報告,並可以將其限制爲特定實例。

例子:

// this suppresses warnings that might result if there is no field titled "field" in the result 
$field_value = @mysql_result($result, 0, "field"); 
+1

這聽起來像用戶希望能夠捕獲錯誤,不surpress它。 – pgreen2 2012-11-29 04:42:21

3
ini_set('mysql.trace_mode', 1) 

可能是你在找什麼。

的PHP錯誤然後可以用自定義的PHP錯誤處理程序處理,但你也可以只是關閉顯示PHP錯誤,因爲它們通常被記錄到日誌文件(取決於你的PHP配置)。