PHP mysql,pdo和查询:为什么多个'查询'不起作用(在这种情况下)?

时间:2012-04-28 17:20:40

标签: php mysql pdo

这是我的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;
}

如何在一次拍摄中获取最后插入的值(=使我所做的工作)?

1 个答案:

答案 0 :(得分: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)