2011-06-04 16 views
15

我正在阅读如何使用PHP插入和更新数据到MySQL表格的教程,代码如下。我的问题是,当我点击更新,但我没有修改任何数据,rowCount()返回0,并打破代码。为什么PDO rowCount()在更新表之后返回0而不修改现有数据?

我的问题是,如果我只是更新与数据库中相同的值的数据库,为什么rowCount()返回零?我的想法是,即使它是相同的数据,它将被插入,并返回更新的行数?我猜测它在尝试更新之前检查数据?任何人都可以为我阐明这一点,并提出一个解决方法?我已经在代码上主演了几个小时,并且一直无法提供任何内容,谢谢。

<?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> 

回答

19

我的问题是,如果我简单地更新与在数据库中的值相同的数据库,为什么rowCount时()返回零?

rowCount正在计算受查询影响的受影响的行。由于你没有改变任何东西,所以没有受到影响的行。

PDOStatement->rowCount - 返回受上一SQL语句

+0

但我插入相同的数据回到行中,有数据在那里它只是相同的数据。它如何知道它们的区别?谢谢 – Drewdin 2011-06-04 14:21:45

+0

你没有插入,你正在更新。有很大的不同,SQL服务器足够聪明,知道他们是否需要做任何工作。如果您没有连续更改数据,则很难将其视为“受影响”。 – ceejayoz 2011-06-04 14:22:25

+0

你如何建议我检查数据是否未被修改?谢谢 – Drewdin 2011-06-04 14:32:41

9

它无关,与PHP的行数 - 这是MySQL的是如何工作的。

MySQL documentations says:

对于UPDATE声明,默认情况下,受影响的行值是行数实际改变。如果在连接到mysqld时指定CLIENT_FOUND_ROWS标志为mysql_real_connect(),则受影响的行值为“找到”的行数;即通过WHERE子句进行匹配。

+0

我很欣赏它,我不明白它是如何工作的。谢谢 – Drewdin 2011-06-04 14:53:02

+3

PDO版本:'$ connection = new PDO($ data_source,$ user,$ password,array(PDO :: MYSQL_ATTR_FOUND_ROWS => true));' – 2016-08-17 14:15:42

2

这是MySQL的工作原理,与PDO扩展本质上没有任何关系;执行常规的mysql查询会产生相同的结果。我使用mysql函数找到了一种解决方法,但我不确定是否可以执行与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 

希望这会有所帮助。

+0

谢谢我同时使用mysqli和pdo版本,生病试试 – Drewdin 2011-06-04 14:52:29

3

当您使用UPDATE语句,并且您提交的数据库中的值相同时,它将始终返回零,因为它不会影响任何行。

来解决这个问题的方法是:

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

我干了什么? 我这样做:

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

因为如果rowCount时()为零,但$ stmt是已执行没有错误$ stmt是被执行了,但没有任何改变。