【问题标题】:Show WARNINGS in MySQL + PDO在 MySQL + PDO 中显示警告
【发布时间】:2013-06-24 13:33:55
【问题描述】:

我想知道如何在 MySQL + PDO 中获取警告计数。

我在控制台中进行查询时遇到警告,正在寻找 varchar 而没有添加撇号 (' ')。

mysql> describe keywords;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| document_id | int(11)      | NO   | MUL | NULL    |                |
| keyword     | char(50)     | NO   |     | NULL    |                |
| value       | varchar(250) | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> select * from keywords where value = 1234567890;
+-----+-------------+--------------------+------------+
| id  | document_id | keyword            | value      |
+-----+-------------+--------------------+------------+
| 311 |          71 | Nº de Operacion   | 1234567890 |
+-----+-------------+--------------------+------------+
1 row in set, 12 warnings (0.00 sec)

mysql> show warnings;
+---------+------+---------------------------------------------------------+
| Level   | Code | Message                                                 |
+---------+------+---------------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '1234-0'              |

我有一个参数化查询,我想知道该查询是否也在生成警告,或者在参数化时值是字符串还是整数无关紧要。

例子:

'SELECT * FROM keywords WHERE value = :value'

适用于搜索整数和字符串,或者我应该添加撇号:

'SELECT * FROM keywords WHERE value = \':value\''

用于搜索 varchar。顺便说一句,没有给出结果。

【问题讨论】:

标签: php mysql pdo


【解决方案1】:

嗯,据我所知,除了显式运行SHOW WARNINGS 查询外,没有其他办法。

但老实说,我认为在 PHP 中出现 mysql 警告并没有多大意义。仅在开发阶段需要它们,但在实时服务器上根本不应该有任何引发警告的查询。

关于您对截断值的怀疑 - 它们是毫无根据的。准备好的陈述不是你想象的那样工作。当使用准备好的语句时,PDO 将永远不会生成可能引发此类警告的查询。

只需去掉这些错误的引号,运行正确的查询并查看:

$stm = $pdo->prepare('SELECT * FROM keywords WHERE value = :value');
$stm->execute(array(':value'=>'whatever'));
$stm = $pdo->query('SHOW WARNINGS');
var_dump($stm->fetchAll());

【讨论】:

  • +1...我只是查看了 OP 正在谈论的实际警告...在我的答案中添加了一个编辑,我为自己是一个任性的笨蛋而道歉;)
  • 如果您的列是长度为 25 的字符串但您插入了 26 个字符的字符串怎么办?我认为 PDO 不会抛出异常,但你的价值被搞砸了?
  • +1 为 fetchAll(),这是获取那些讨厌的警告的唯一方法。谢谢你。 $stm->errorCode() 或 $stm->errorInfo() 不会删除它。
  • @CappY 如果您的列是长度为 25 的字符串,但您插入了 26 个字符的字符串,并且设置了 ERRMODE_EXCEPTION,那么 PDO 肯定会抛出异常
【解决方案2】:

在构建您的 PDO 实例时,传递一个包含此键值对的选项数组:

array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)

在发生错误时强制 PDO 抛出异常(PDOException 实例)。此外,在使用准备好的语句时,您不要添加自己的引号......如果值是字符串,

WHERE value = :value

没关系,PDO/MySQL 会为您正确引用该值。

PS:您以后可以随时更改错误模式,方法是调用setAttribute

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);//raise warnings, don't throw errors

Here's a list of attributes
Here, you'll find examples where options are set via the constructor

文档页面中的示例,仅扩展了一点:

$pdo = new PDO('mysql:host=myhost;dbname=mydb', 'login', 'password',
    array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',
          PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
          PDO::ATTR_ORACLE_NULLS       => PDO::NULL_NATURAL)
);

编辑:
再次浏览您的问题后,我注意到实际警告您收到了。该警告显然不会抛出异常。准备好的语句在准备好语句时检查数据类型,完成该工作后,将执行该语句。在您的情况下,将双精度转换为 varchar,然后执行查询,将 value 中的 varchars 与查询中的 varchar 进行比较。没有警告,没有大惊小怪,它只是完成工作
Here's a related question
And here's a more detailed explanation on how prepares work

【讨论】:

  • 好的,自动引用的部分是答案的 50%,谢谢!。另一部分,在 PDO 中是​​否将 WARNINGS 转换为 ERRORS?
  • @Jorge:是的,您必须将executequery 或任何调用包装在try-catch 中,并使用$e->getCode(); 来获取SQLSTATE。然后,您可以选择忽略、显示、回滚或重复查询(当然,在解决问题之后)。 More details can be found in the docs, as ever
  • @Jorge 请不要听这个。实际上,您不应该将您的执行、查询或任何调用包装在 try-catch 中。
  • 仍然没有明白这一点。即使有警告,也没有办法通过 PDO 错误处理程序获取它。
  • @YourCommonSense: not a PHP-only way, no,但您可以按照 PHP 邮件列表显示的方式设置配置
猜你喜欢
  • 2022-06-18
  • 1970-01-01
  • 2014-11-01
  • 2010-09-11
  • 2011-06-14
  • 2014-12-19
  • 2023-04-02
  • 1970-01-01
相关资源
最近更新 更多