2008-09-06 70 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配置)。