mysqli::prepare Fails Using ALTER TABLE in a Statement With Parameter Markers

m

Part of a project I’m working on requires re-setting a MySQL table by deleting most – but not all – rows. In PHP I’m using mysqli::prepare to prepare the MySQL statements.

$id = 5;
$query = $conn->prepare("DELETE FROM table WHERE id>?");

 

 

The MySQL statement includes a parameter marker – denoted by ? – which is then substituted for the value of the $id variable using mysqli::bind_param.

$id = 5;
$query = $conn->prepare("DELETE FROM table WHERE id>?");
$query->bind_param("i", $id);

 

 

To execute the statement, mysqli::execute is added.

$id = 5;
$query = $conn->prepare("DELETE FROM table WHERE id>?");
$query->bind_param("i", $id);
$query->execute();

 

 

I’ve heard that this is not best practice, but – having deleted rows – I wanted to update the table’s AUTO_INCREMENT value. The value can be obtained by adding 1 to table’s current row count.

$rows++;
$query = $conn->prepare("ALTER TABLE table AUTO_INCREMENT=?");
$query->bind_param("i", $rows);
$query->execute();

 

 

This throws the following error which suggests an issue with the parameters passed to $query‑>bind_param() on line 8.

Fatal error: Uncaught Error: Call to a member function bind_param() on boolean in /var/www/bookmarks/public_html/delete.php8 Stack trace: #0 {main} thrown in /var/www/bookmarks/public_html/delete.php on line 8

 

 

However, after some considerable head scratching the real culprit is $query = $conn‑>prepare(“ALTER TABLE table AUTO_INCREMENT=?”); which I discovered by testing the value returned by $conn->prepare().

$rows++;
$query = $conn->prepare("ALTER TABLE table AUTO_INCREMENT=?");
if ( $query===false) {
	echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
}

 

 

This displays the following error.

Prepare failed: (1064) You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'table AUTO_INCREMENT=?' at line 10

 

 

It appears there’s an error in the MySQL statement, namely the ? at the end. But, this ? is the parameter marker to be substituted by mysql::bind_param with the value of the variable $rows. The parameter marker worked in the previous statement when deleting rows so why not in this one?

More head scratching. Then – having read the mysql::prepare documentation for the umpteenth time – I noticed this at the end of a paragraph I’d previously dismissed because it didn’t specifically mention ALTER TABLE or AUTO_INCREMENT.

In general, parameters are legal only in Data Manipulation Language (DML) statements, and not in Data Definition Language (DDL) statements.

DELETE – it turns out – is a DML statement. However, ALTER TABLE is a DDL statement hence the reason mysqli::prepare failed in this instance when using a parameter marker.

About the author

A native Brit exiled in Japan, Steve spends too much of his time struggling with the Japanese language, dreaming of fish & chips and writing the occasional blog post he hopes others will find helpful.

Add comment

Steve

Recent Comments

Recent Posts