2011-06-04 34 views
15

Estoy leyendo un tutorial sobre cómo insertar y actualizar datos en una tabla MySQL utilizando PHP, el código se enumera a continuación. Mi problema es cuando hago clic en actualizar pero no he modificado ningún dato, rowCount() devuelve 0 y rompe el código.¿Por qué PDO rowCount() devuelve 0 después de ACTUALIZAR una tabla sin modificar los datos existentes?

Mi pregunta es, si simplemente estoy actualizando la base de datos con los mismos valores que están en la base de datos, ¿por qué rowCount() devuelve cero? ¿Mi opinión era que, a pesar de que era la misma información, se insertaría de todos modos y devolvería un recuento de las filas actualizadas? ¿Supongo que verifica los datos antes de intentar la actualización? ¿Alguien puede arrojar algo de luz sobre esto para mí y sugerir una solución alternativa? He estado protagonizando el código durante horas y no he podido encontrar nada, gracias.

<?php 
require_once('../includes/connection.inc.php'); 
// initialize flags 
$OK = false; 
$done = false; 
// create database connection 
$conn = dbConnect('write', 'pdo'); 
if (isset($_GET['article_id']) && !$_POST) { 
    // prepare sql query 
    $sql = 'SELECT article_id, title, article FROM blog WHERE article_id = ?'; 
    $stmt = $conn->prepare($sql); 
    // bind the results 
    $stmt->bindColumn(1, $article_id); 
    $stmt->bindColumn(2, $title); 
    $stmt->bindColumn(3, $article); 
    // execute query by passing array of variables 
    $OK = $stmt->execute(array($_GET['article_id'])); 
    $stmt->fetch(); 
} 
// if form has been submitted, update record 
if (isset($_POST['update'])) { 
    //prepare update query 
    $sql = 'UPDATE blog SET title = ?, article = ? WHERE article_id = ?'; 
    $stmt = $conn->prepare($sql); 
    // execute query by passing array of variables 
    $stmt->execute(array($_POST['title'], $_POST['article'], $_POST['article_id'])); 
    $done = $stmt->rowCount(); 
} 
// redirect page on sucess or if $_GET['article_id'] not defined 
if ($done || !isset($_GET['article_id'])) { 
    header('Location: http://localhost/PHP_Solutions/admin/blog_list_pdo.php'); 
    exit(); 
} 
// store error message if query fails 
if (isset($stmt) && !$OK && !$done) { 
    $error = $stmt->errorInfo(); 
    if (isset($error[2])) { 
     $error = $error[2]; 
    } 
} 
?> 
<!DOCTYPE HTML> 
<html> 
<head> 
<meta charset="utf-8"> 
<title>Update Blog Entry</title> 
<link href="../styles/admin.css" rel="stylesheet" type="text/css"> 
</head> 

<body> 
<h1>Update Blog Entry</h1> 
<p><a href="blog_list_pdo.php">List all entries </a></p> 
<?php if (isset($error[2])) { 
    echo "<p class='warning'>Error: $error[2]</p>"; 
    echo '<pre>'; 
    print_r($_POST); 
    print_r($error); 
    echo '</pre>'; 
} 
if ($article_id == 0) { ?> 
    <p class="warning">Invalid request: record does not exist.</p> 
<?php } else { ?> 
<form id="form1" method="post" action=""> 
    <input name="article_id" type="hidden" value="<?php echo $article_id; ?>"> 
    <p> 
    <label for="title">Title:</label> 
    <input name="title" type="text" class="widebox" id="title" value="<?php echo htmlentities($title, ENT_COMPAT, 'utf-8'); ?>"> 
    </p> 
    <p> 
    <label for="article">Article:</label> 
    <textarea name="article" cols="60" rows="8" class="widebox" id="article"><?php echo htmlentities($article, ENT_COMPAT, 'utf-8'); ?></textarea> 
    </p> 
    <p> 
    <input type="submit" name="update" value="Update Entry" id="update"> 
    </p> 
</form> 
<?php } ?> 
</body> 
</html> 

Respuesta

19

Mi pregunta es, si yo soy simplemente actualizando la base de datos con los mismos valores que están en la base de datos, ¿por qué rowCount() devuelven cero?

rowCount está contando los afectados filas por una consulta. Como no ha cambiado nada, no hay filas afectadas.

PDOStatement->rowCount - Devuelve el número de filas afectadas por la última sentencia SQL

+0

pero estoy insertando los mismos datos en las filas, hay datos allí son exactamente los mismos datos. ¿Cómo sabe la diferencia? Gracias – Drewdin

+0

No estás insertando, estás actualizando. Hay una gran diferencia, y los servidores SQL son lo suficientemente inteligentes como para saber si tuvieron que hacer algún trabajo o no. Si no cambia los datos en una fila, difícilmente puede considerarse 'afectado'. – ceejayoz

+0

¿cómo me recomiendan verifico si los datos no han sido modificados? Gracias – Drewdin

9

No tiene nada que ver con PHP - es sólo cómo funciona MySQL.

MySQL documentations says:

Para UPDATE declaraciones, el valor de registros afectados por defecto es el número de filas en realidad cambió. Si especifica el indicador CLIENT_FOUND_ROWS en mysql_real_connect() al conectarse al mysqld, el valor de las filas afectadas es el número de filas "encontradas"; es decir, emparejado por la cláusula WHERE.

+0

Lo aprecio, no entiendo cómo funcionó. Gracias – Drewdin

+3

versión DOP: 'conexión $ = new PDO ($ data_source, $ usuario, $ password, array (PDO :: MYSQL_ATTR_FOUND_ROWS => true));' –

2

Así es como funciona MySQL y no tiene nada que ver intrínsecamente con la extensión PDO; realizar una consulta mysql regular produciría los mismos resultados. Hay una solución alternativa que encontré usando las funciones de mysql, aunque no estoy seguro si puedes hacer algo similar con un objeto PDO.

$q = 'UPDATE etc...'; 
$r = mysql_query($q, $con); 
$info = mysql_info(); // Returns info about last query. 

list($matches, $changed, $warnings) = sscanf($matched, "Rows matched: %d Changed: %d Warnings: %d"); 

if ($matches > 0) {} // etc 

Espero que esto ayude un poco.

+0

Gracias que tengo las dos versiones mysqli y PDO ir, los malos tratar de que fuera – Drewdin

3

Cuando está utilizando la instrucción UPDATE y envía los mismos valores que están en la base de datos, siempre devolverá cero, porque no afecta a ninguna fila.

Una manera de resolver este problema es:

$done = $stmt !== false ? true : false; 

lo que hice? lo hice:

if($stmt !== false){ 
    $done = true; 
} else{ 
    $done = false; 
} 

Porque si rowCount() es cero, pero $ prop ha ejecutado sin errores , $ STMt fue ejecutado, pero no cambia nada.

Cuestiones relacionadas