• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • mysqli::$affected_rows()

    (PHP 5, PHP 7)

    Gets the number of affected rows in a previous MySQL operation

    说明

    面向对象风格
    int $mysqli->affected_rows;
    过程化风格
    mysqli_affected_rows(mysqli$link): int

    Returns the number of rows affected by the lastINSERT,UPDATE,REPLACEorDELETEquery.

    For SELECT statements mysqli_affected_rows() works like mysqli_num_rows().

    参数

    $link

    仅以过程化样式:由mysqli_connect()或mysqli_init()返回的链接标识。

    返回值

    An integer greater than zero indicates the number of rows affected or retrieved. Zero indicates that no records were updated for an UPDATE statement, no rows matched theWHEREclause in the query or that no query has yet been executed.-1 indicates that the query returned an error.

    Note:

    If the number of affected rows is greater than the maximum integer value(PHP_INT_MAX), the number of affected rows will be returned as a string.

    范例

    Example #1$mysqli->affected_rowsexample

    面向对象风格

    <?php
    $mysqli = new mysqli("localhost", "my_user", "my_password", "world");
    /* check connection */
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }
    /* Insert rows */
    $mysqli->query("CREATE TABLE Language SELECT * from CountryLanguage");
    printf("Affected rows (INSERT): %d\n", $mysqli->affected_rows);
    $mysqli->query("ALTER TABLE Language ADD Status int default 0");
    /* update rows */
    $mysqli->query("UPDATE Language SET Status=1 WHERE Percentage > 50");
    printf("Affected rows (UPDATE): %d\n", $mysqli->affected_rows);
    /* delete rows */
    $mysqli->query("DELETE FROM Language WHERE Percentage < 50");
    printf("Affected rows (DELETE): %d\n", $mysqli->affected_rows);
    /* select all rows */
    $result = $mysqli->query("SELECT CountryCode FROM Language");
    printf("Affected rows (SELECT): %d\n", $mysqli->affected_rows);
    $result->close();
    /* Delete table Language */
    $mysqli->query("DROP TABLE Language");
    /* close connection */
    $mysqli->close();
    ?>
    

    过程化风格

    <?php
    $link = mysqli_connect("localhost", "my_user", "my_password", "world");
    if (!$link) {
        printf("Can't connect to localhost. Error: %s\n", mysqli_connect_error());
        exit();
    }
    /* Insert rows */
    mysqli_query($link, "CREATE TABLE Language SELECT * from CountryLanguage");
    printf("Affected rows (INSERT): %d\n", mysqli_affected_rows($link));
    mysqli_query($link, "ALTER TABLE Language ADD Status int default 0");
    /* update rows */
    mysqli_query($link, "UPDATE Language SET Status=1 WHERE Percentage > 50");
    printf("Affected rows (UPDATE): %d\n", mysqli_affected_rows($link));
    /* delete rows */
    mysqli_query($link, "DELETE FROM Language WHERE Percentage < 50");
    printf("Affected rows (DELETE): %d\n", mysqli_affected_rows($link));
    /* select all rows */
    $result = mysqli_query($link, "SELECT CountryCode FROM Language");
    printf("Affected rows (SELECT): %d\n", mysqli_affected_rows($link));
    mysqli_free_result($result);
    /* Delete table Language */
    mysqli_query($link, "DROP TABLE Language");
    /* close connection */
    mysqli_close($link);
    ?>
    

    以上例程会输出:

    Affected rows (INSERT): 984
    Affected rows (UPDATE): 168
    Affected rows (DELETE): 815
    Affected rows (SELECT): 169
    

    参见

    • mysqli_num_rows() Gets the number of rows in a result
    • mysqli_info() 返回最近执行的 SQL 语句的信息
    On "INSERT INTO ON DUPLICATE KEY UPDATE" queries, though one may expect affected_rows to return only 0 or 1 per row on successful queries, it may in fact return 2.
    From Mysql manual: "With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row and 2 if an existing row is updated."
    See: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
    Here's the sum breakdown _per row_:
    +0: a row wasn't updated or inserted (likely because the row already existed, but no field values were actually changed during the UPDATE)
    +1: a row was inserted
    +2: a row was updated
    If you need to know specifically whether the WHERE condition of an UPDATE operation failed to match rows, or that simply no rows required updating you need to instead check mysqli::$info.
    As this returns a string that requires parsing, you can use the following to convert the results into an associative array.
    Object oriented style:
    <?php
      preg_match_all ('/(\S[^:]+): (\d+)/', $mysqli->info, $matches); 
      $info = array_combine ($matches[1], $matches[2]);
    ?>
    Procedural style:
    <?php
      preg_match_all ('/(\S[^:]+): (\d+)/', mysqli_info ($link), $matches); 
      $info = array_combine ($matches[1], $matches[2]);
    ?>
    You can then use the array to test for the different conditions
    <?php
      if ($info ['Rows matched'] == 0) {
        echo "This operation did not match any rows.\n";
      } elseif ($info ['Changed'] == 0) {
        echo "This operation matched rows, but none required updating.\n";
      }
      if ($info ['Changed'] < $info ['Rows matched']) {
        echo ($info ['Rows matched'] - $info ['Changed'])." rows matched but were not changed.\n";
      }
    ?>
    This approach can be used with any query that mysqli::$info supports (INSERT INTO, LOAD DATA, ALTER TABLE, and UPDATE), for other any queries it returns an empty array.
    For any UPDATE operation the array returned will have the following elements:
    Array
    (
      [Rows matched] => 1
      [Changed] => 0
      [Warnings] => 0
    )
    While using prepared statements, even if there is no result set (Like in an UPDATE or DELETE), you still need to store the results before affected_rows returns the actual number:
    <?php
    $del_stmt->execute();
    $del_stmt->store_result();
    $count = $del_stmt->affected_rows;
    ?>
    Otherwise things will just be frustrating ..
    <?php
      $gHostName  ="localhost";  
      $gUserName  ="root";
      $gPassword  ="mypassword";
      $gDBName   ="dbName";
      $mysqli = new mysqli($gHostName, $gUserName, $gPassword,   
          $gDBName);
      
      $username="username";  $email="user@xxx.edu";
      $password="3442f6e94a733237a3e844f0286b92f559bf794d";
      
      //insert
    //  $stmt = $mysqli->prepare("INSERT INTO j_user 
        (username,email,password) VALUES (?, ?, ?)");
    //  $stmt->bind_param('sss',$username, $email, $password);
    //  $stmt->execute();
    //  $stmt->close();
      //delete
    //  $stmt = $mysqli->prepare("DELETE FROM j_user WHERE 
                username=?");
    //  $stmt->bind_param('s',$username);
    //  $stmt->execute();
    //  $stmt->close();
      //update
    //  $stmt = $mysqli->prepare("UPDATE j_user SET email=? WHERE 
                username='wjw6349'");
    //  $stmt->bind_param('s',$email);
    //  $stmt->execute();
    //  $stmt->close();
      if ($mysqli->connect_error){
        echo("Connect failed: ".mysqli_connect_error()); exit();
      }
      $querySelect = "SELECT * FROM j_user";
      $resultSet = $mysqli->query($querySelect);
      
      if($resultSet->num_rows > 0){
        while($row = $resultSet->fetch_assoc()){
          foreach($row as $fieldValue){
            $bigString .= "<em>$fieldValue</em><br />\n";
          }
          $bigString .= "<hr />";
        }
        $mysqli->close();
        echo $bigString;
      }
      function __autoload($className) {
        require_once $className.'.class.php';
      }
      //start the session and create it
      session_start();
      $_SESSION['name'] = $_POST['username']."_".time();
      //encrypt the password  
      sha1($_POST['password']) == $password
      header("Location:admin.php");
      //check if the session is set
      session_start();
      if (isset($_SESSION['name'])) { }
    ?>
    
    empty($db->affected_rows) will return TRUE even if affected_rows is greater than 0. Manually check < 1 if you're looking for failure.
    "Zero indicates that no records where updated for an UPDATE statement, no rows matched the WHERE clause in the query or that no query has yet been executed."
    what if i need to know which one of the three occurred? It's dumb that there is no distinction between the three.
    This may seem obvious, but if you do an UPDATE with each of the values in your SET clause having the exact same value that is already in the table, then affected_rows returns 0. For example:
    <?php
      $mysqli = new mysqli($host, $usr, $pwd, $db, $port);
      $appointment_date = "2015-12-07";
      $sql = "update appointments set appointment_date = ? where appointment_id = 78";
      $stmt = $mysqli->prepare($sql);
      $stmt->bind_param("s",$appointment_date);
      $stmt->execute();
      echo $mysqli ->affected_rows . "<br>";
    ?>
    This returns 1 the first time I run it after changing the value of the $appointment_date variable. When I run it a second time (making no changes), it returns 0. I also verified the same behavior without using prepared statements.
    For "INSERT" or "UPDATE" statement for modifying data contained in one row of one table I checked if number of affected rows equals 1 to determine success of the operation. It works fine both for errors and false value of WHERE condition (that might be generated according to specific application user acces privileges).
    <?php
    if ($mysqli->affected_rows==1){
      echo "success";
    }
    else {
      echo "fail";
    }
    ?>
    Checking if mysqli->affected_rows will equal -1 or not is not a good method of determining success of "INSERT IGNORE" statements. Example: Ignoring duplicate key errors while inserting some rows containing data provided by user only if they will match specified unique constraint causes returning of -1 value by mysqli->affected_rows even if rows were inserted. (checked on MySQL 5.0.85 linux and php 5.2.9-2 windows). However mysqli->sqlstate returns no error if statement was executed successfully.
    <?php
    if ($mysqli->affected_rows!=-1){
      echo "success";// for "INSERT IGNORE" statements will not occur if there were any duplicate key errors ignored during execution of the query
    }
    else {
      echo "fail";// "INSERT IGNORE" statements causing any duplicate key errors (however ignored) lead to mysqli->affected_rows equal -1
    }
    // Example below works for "INSERT IGNORE" stattements, too
    if ($mysqli->sqlstate=="00000"){
      echo "success";
    }
    else {
      echo "fail";
    }
    ?>