Here's my sql request:
$sql
= 'CREATE TEMPORARY TABLE tmp '
. 'SELECT * FROM '.$table.' '
. 'WHERE id=:id; '
. 'ALTER TABLE tmp drop ID; '
. 'INSERT INTO '.$table.' '
. 'SELECT 0,tmp.* FROM tmp; '
. 'SET @last=LAST_INSERT_ID(); '
. 'DROP TABLE tmp;'
. 'SELECT @last; ';
$stmt = $this->bd->execQuery($sql, array(':id'=>101));
echo "1 -> = "; var_export($stmt); echo "\n";
$stmt = $stmt->fetch(PDO::FETCH_OBJ);
echo "2 -> = "; var_export($stmt); echo "\n";
The dump talk by itself: the query works (I've checked).
sql =
'CREATE TEMPORARY TABLE tmp SELECT * FROM categorie WHERE id=:id; ALTER TABLE tmp drop ID; INSERT INTO categorie SELECT 0,tmp.* FROM tmp; SET @last=LAST_INSERT_ID(); DROP TABLE tmp;SELECT @last; '
params = array (
':id' => 101,
)
1 -> = PDOStatement::__set_state(array(
'queryString' => 'CREATE TEMPORARY TABLE tmp SELECT * FROM categorie WHERE id=:id; ALTER TABLE tmp drop ID; INSERT INTO categorie SELECT 0,tmp.* FROM tmp; SET @last=LAST_INSERT_ID(); DROP TABLE tmp;SELECT @last; ',
))
2 -> = false
If I do it "by hand" on the console line it works too (sorry for the looong line of code):
mysql> CREATE TEMPORARY TABLE tmp SELECT * FROM categorie WHERE id=101; ALTER TABLE tmp drop ID; INSERT INTO categorie SELECT 0,tmp.* FROM tmp; SET @last=LAST_INSERT_ID(); DROP TABLE tmp;SELECT @last;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
Query OK, 1 row affected (0.07 sec)
Records: 1 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
+-------+
| @last |
+-------+
| 141 |
+-------+
1 row in set (0.00 sec)
mysql>
Here's my code that is being executed.
public function execQuery($sql, $tab=array())
{
$stmt = self::$_pdo->prepare($sql);
if ($stmt===false) {
throw new Exception(
'Erreur prepare '.$sql.
' = '.var_export(self::$_pdo->errorInfo(), true)
);
}
foreach ($tab as $key=>$valeur) {
$stmt->bindValue($key, $valeur);
}
if ($stmt->execute()===false) {
throw new Exception(
"Erreur execution de la requete :\n\"".$sql."\"\n".
"Paramètres de la requete :\n\"".var_export($tab, true)."\"\n".
"Details de l'erreur : \n".var_export(self::$_pdo->errorInfo(), true)
);
}
return $stmt;
}
How can I do to get the last inserted value in one shot (= make what I did work)?
Multiple statements or multi queries must be executed with mysqli::multi_query(). The individual statements of the statement string are separated by semicolon. Then, all result sets returned by the executed statements must be fetched.
How check PDO query is successful in PHP? To determine if the PDO::exec method failed (returned FALSE or 0), use the === operator to strictly test the returned value against FALSE.
PDO::query() prepares and executes an SQL statement in a single function call, returning the statement as a PDOStatement object.
Execute: At a later time, the application binds the values to the parameters, and the database executes the statement. The application may execute the statement as many times as it wants with different values.
As mentioned in my comment above, whilst it doesn't answer your question of how you issue multiple SQL commands in one query from PHP, one workaround would be to put your SQL in a stored procedure using a prepared statement:
DELIMITER ;;
CREATE PROCEDURE copyRecord(TableName VARCHAR(20), id INT) BEGIN
-- prevent SQL injection
SET TableName = CONCAT('`', REPLACE(TableName, '`', '``'), '`');
SET @id = id;
SET @sql = CONCAT('
CREATE TEMPORARY TABLE tmp SELECT * FROM ', TableName, ' WHERE id = ?
');
PREPARE stmt FROM @sql;
EXECUTE stmt USING @id;
DEALLOCATE PREPARE stmt;
ALTER TABLE tmp drop ID;
SET @sql = CONCAT('
INSERT INTO ', TableName, ' SELECT 0,tmp.* FROM tmp
');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE tmp;
SET @sql = NULL;
SET @id = NULL;
SELECT LAST_INSERT_ID();
END;;
DELIMITER ;
From PHP you would then simply invoke the SQL command CALL copyRecord('categorie', 101)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With