4

I'd like to know how to get warning count in MySQL + PDO.

I was having warnings when making a query in console, looking for varchar and not adding aphostrophes (' ').

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'              |

I have a parametrized query, and I'd like to know if that query is generating warnings too, or if it doesn't matter if the value is string or integer when you parametrize it.

Example:

'SELECT * FROM keywords WHERE value = :value'

Would work for searching integers and strings, or should I add aphostrophes:

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

for searching a varchar. Which by the way, doesn't give results.

JorgeeFG
  • 5,651
  • 12
  • 59
  • 92
  • Read the manual. [Errors and error handling](http://php.net/manual/en/pdo.error-handling.php); [Sets which PHP errors are reported](http://php.net/manual/en/function.error-reporting.php) – Kermit Jun 24 '13 at 13:36
  • See [How to squeeze error message out of PDO?](http://stackoverflow.com/q/3726505) – Pekka Jun 24 '13 at 13:38
  • 3
    Looks like noone understands **mysql** warnings – Your Common Sense Jun 24 '13 at 13:53

2 Answers2

12

Well, as far as I know, there is no way except explicitly run SHOW WARNINGS query.

But honestly, I see not much point in having mysql warnings in PHP. One need them in a development phase only, but on a live server there should be no query that raise a warning at all.

Concerning your doubts on truncated values - they're groundless. Prepared statements works not the way you are thinking of. PDO will never produce a query that may raise a warning like this when prepared statements are used.

Just get rid of these wrong quotes, run the proper query and see:

$stm = $pdo->prepare('SELECT * FROM keywords WHERE value = :value');
$stm->execute(array(':value'=>'whatever'));
$stm = $pdo->query('SHOW WARNINGS');
var_dump($stm->fetchAll());
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • 1
    +1... I just looked at the actual warning the OP was talking about... added an edit to my answer, and I appologize for being a headstrong twat ;) – Elias Van Ootegem Jun 24 '13 at 14:34
  • 3
    What about if your column is string 25 lenght but you insert 26 characters string? I think PDO won't throw exception but your value is screwed up? – CappY Mar 04 '15 at 12:21
  • +1 for the fetchAll(), it's the only way to get hold of those pesky warnings. Thank you. $stm->errorCode() or $stm->errorInfo() won't cut it. – Gen.Stack Dec 16 '20 at 22:16
  • @CappY if your column is string 25 lenght but you insert 26 characters string, and `ERRMODE_EXCEPTION` is set then PDO will definitely throw an exception – Anton Belonovich Mar 27 '22 at 10:17
  • Use [this](https://www.php.net/manual/en/pdo.constants.php) combined with [this](https://www.php.net/manual/en/pdo.errorcode.php) to check for errors OR warnings. AFAI know, cropped inserts do not generate errors, but warnings; sou you'd miss them out, if I'm not wrong. Others (like [this one](https://stackoverflow.com/questions/38631639/pdo-dblib-not-catching-warnings) seem to confirm this) – DevelJoe Jun 17 '22 at 15:11
3

When constructing your PDO instance, pass an array of options, containing this key-value pair:

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

To force PDO to throw exceptions (PDOException instances) when an error occurs. Also, when using prepepared statements, you don't add quotes of your own... if the value is a string,

WHERE value = :value

Is just fine, PDO/MySQL will quote the value correctly for you.

PS: You can always change the error mode later on, by calling 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

example from the doc pages, only extended a bit:

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

Edit:
After a second glance at your question, I noticed the actual warning you got. That warning will evidently not throw an Exception. Prepared statements check the datatypes upon statement preparation, after that job is done, the statement gets executed. In your case, the double is cast to a varchar, and then the query is executed, comparing the varchars in value with the varchar in the query. No warnings, no fuss, it just does the job.
Here's a related question
And here's a more detailed explanation on how prepares work

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • Ok the part of the auto-quoting is 50% of the answer, thanks!. The other part, are WARNINGS converted into ERRORS in PDO? – JorgeeFG Jun 24 '13 at 13:54
  • @Jorge: Yes, you'll have to wrap your `execute`, `query` or whatever call in a try-catch, and use `$e->getCode();` to get the SQLSTATE. You can then choose to ignore, display, rollback or repeat the query (after adressing the issue, of course). [More details can be found in the docs, as ever](http://www.php.net/manual/en/pdo.error-handling.php) – Elias Van Ootegem Jun 24 '13 at 13:57
  • @Jorge please don't listen to this one. Actually you **should not** wrap your execute, query or whatever call in a try-catch. – Your Common Sense Jun 24 '13 at 14:00
  • You *still* don't get the point. Even if there was a warning, there is **no way** to get it through PDO error handler. – Your Common Sense Jun 24 '13 at 14:41
  • @YourCommonSense: [not a PHP-only way, no](http://osdir.com/ml/php-db/2012-08/msg00030.html), but you can set the config as the PHP mailinglist shows – Elias Van Ootegem Jun 24 '13 at 14:53