2012-02-22 12 views
5

Me encontré con este problema en una de mis aplicaciones web en vivo. Parece que si emite una consulta de instrucciones múltiples a MySQL mediante PHP PDO, y la primera instrucción es una instrucción de inserción, y la segunda instrucción es una declaración de actualización, la función PDO :: nextRowset() no devuelve el número correcto de conjuntos de resultados. (Tenga en cuenta que DOP supuestamente soporta múltiples declaraciones por consulta MySQL desde PHP 5.3.)Error de PHP PDO en la consulta de varias afirmaciones

He aquí un ejemplo:

SQL:

create database `test`character set utf8 collate utf8_general_ci; 
create table `test`.`testtable`(`id` int); 

PHP:

<?php 
$link = new \PDO('mysql:host=localhost;dbname=test', 'username', 'password'); 

//Run one of the 4 $handle assignments at a time (comment out all but one). 
//Run #4 on an empty table to compare the results of #1 and #4. 

//WORKS: INSERT, followed by SELECT, followed UPDATE 
//Output: 
//Rowset 1 
//Rowset 2 
//Results detected 
$handle = $link->prepare(' insert into testtable(id) values(1); 
          select * from testtable where id = ?; 
          update testtable set id = 2 where id = ?;'); 


//WORKS: SELECT, followed by UPDATE 
//Output: 
//Rowset 1 
//Results detected 
$handle = $link->prepare('select * from testtable where id = ?; 
          update testtable set id = 2 where id = ?;'); 

//WORKS: UPDATE, followed by SELECT 
//Output: 
//Rowset 1 
//Rowset 2 
//Results detected 
$handle = $link->prepare('select * from testtable where id = ?; 
         update testtable set id = 2 where id = ?;'); 


//DOESN'T WORK: INSERT, followed by UPDATE, followed by SELECT 
//Output: 
//Rowset 1 
//Expected output: same as examples 1 and 3 
$handle = $link->prepare('insert into testtable(id) values(1); 
          update testtable set id = 2 where id = ?; 
          select * from testtable where id = ?;'); 

$handle->bindValue('1', '1'); 
$handle->bindValue('2', '2'); 

$handle->execute(); 

$i = 1; 
do{ 
    print('Rowset ' . $i++ . "\n"); 
    if($handle->columnCount() > 0) 
    print("Results detected\n"); 
}while($handle->nextRowset()); 
?> 

¿Alguien tiene alguna idea de lo que estoy haciendo mal? ¿Por qué no puedo poner mi declaración seleccionada al final?

PHP 5.3.5

MySQL 5.1.54

+0

debería estar utilizando \ PDO –

+3

No debe hacer múltiples consultas en una sola llamada de consulta para comenzar. Las bibliotecas de cliente de mysql para PHP, que utiliza PDO, no admiten esto como una defensa de prevención de inyección sql. –

+2

@LawrenceCherone Uno debe, si se está desarrollando dentro de un espacio de nombres – Phil

Respuesta

4

He enviado un PHP bug report sobre este problema y se ha enviado un posible parche. Entonces parece que esto fue un error de PHP.

0
  1. primer lugar, usted tiene que averiguar lo que se vuelve nextRowset() en relación con una operación no seleccione. He tratado de var_dump después de una actualización, y tengo bool (false), lo que puede explicar por qué sólo tiene una salida con:

    $handle = $link->prepare('insert into testtable(id) values(1); 
            update testtable set id = 2 where id = ?; 
            select * from testtable where id = ?;'); 
    
  2. En segundo lugar, he sustituido los siguientes códigos:

    var_dump($h->nextRowset()); 
    var_dump($h->nextRowset()); 
    

    con su segmento do-while, obtuve bool (falso) bool (verdadero), lo que significa que solo va una vez en el ciclo.

    No sé si es correcto explicar su pregunta como la anterior, puede que le ayude.

Cuestiones relacionadas