7

这是我的 sql 请求:

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

转储本身:查询有效(我已经检查过)。

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

如果我在控制台线上“手动”执行它,它也可以工作(对不起,looong 代码行):

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> 

这是我正在执行的代码。

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;
}

我怎样才能一次获得最后插入的值(= 使我所做的工作)?

4

1 回答 1

1

正如我在上面的评论中提到的,虽然它没有回答您如何在一个 PHP 查询中发出多个 SQL 命令的问题,但一种解决方法是使用准备好的语句将您的 SQL 放入存储过程中:

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 ;

然后,您只需从 PHP 调用 SQL 命令CALL copyRecord('categorie', 101)

于 2012-04-28T17:49:47.717 回答