mysqli_query返回0行(奇怪的行为)

时间:2013-07-07 00:16:26

标签: php mysql select mysqli

这个非常简单的方法是从Flash Actionscript应用程序调用的,目的是只删除一条记录。 这是一个包含1000多个脚本的非常大的应用程序,其中许多脚本成功地使用相同的模式......但是这个脚本拒绝表现得像其他脚本。

为了简单起见,我清理了部分代码,对此无意义 正如我之前所说,它非常简单(正如您在代码中看到的那样):

  1. 检查记录是否存在。
  2. 启动MySql事务(START TRANSACTION)
  3. 删除所需记录
  4. 删除/更新其他一些相关信息(在此代码中省略)
  5. 如果一切正常,请执行交易
  6. 问题如下:

    • 如果我按照代码中所示运行脚本,在第一个SELECT状态($ query1)之后,mysqli_num_rows($ result1)返回0(零)记录,尽管我可以在数据库中看到该记录存在。如此,它显然无法删除,跳到脚本的末尾。但是,(这是最奇怪的行为!)记录实际上已被删除。
    • 如果我对COMMIT语句($ query5)发表评论,则mysqli_num_rows($ result1)将返回1(一)。这应该没问题,并且DELETE语句运行正常($ query4)但是由于COMMIT已被注释,因此事务未正确完成,并且所需的记录当然仍保留在数据库中。
    • 如果我注释SELECT语句($ query1)并直接执行DELETE语句($ query4),而不检查记录是否存在,则记录被正确删除,最后一个COMMIT语句($ query5)确认数据库更改。

    我已经逐步跟踪了几个小时,但就目前而言,找不到此代码无法正常运行的原因 我还用mysqli_affected_rows替换了mysqli_num_rows(为了SELECT语句的目的,它会是相同的)但奇怪的行为仍然存在。

    <?php
    function f_ROLLBACK() {
        global $messages;
        global $conexion;
        $query  = "";
        $query .= "ROLLBACK";
        $result = mysqli_query( $conexion, $query);
        if (!$result === true) {
            $messages .= "\nInvalid Query\n".mysqli_error( $conexion )."\nQUERY:".$query;
        } else {
            $messages .= "\nTransaction successful ROLLBACK";
        }//if (!$result === true)
        return;
    }//function f_ROLLBACK
    
    include ("../config/DBconfig.inc.php");
    
    $recID = isset($_POST["recID"]) ? $_POST["recID"] : "5";
    
    $returnVars = array();
    $messages = "";
    $n = 0;
    $now = gmdate("YmdHis");
    
    //check if exists
    $query1  = "";
    $query1 .= "SELECT recID ";
    $query1 .= "    FROM records ";
    $query1 .= " WHERE recID = ".$recID." ";
    
    $result1 = mysqli_query( $conexion, $query1);
    
    if (!$result1 === true) {
        $messages .= "\nInvalid Query\n".mysqli_error( $conexion )."\nQUERY1:".$query1;
    } else {
        $rows1 = mysqli_num_rows($result1);
        if ($rows1 < 1) {
            $messages .= "\nSelected Record could not be found.";
        } else {
    
            $query2  = "";
            $query2 .= "START TRANSACTION";
    
            $result2 = mysqli_query( $conexion, $query2);
    
            if (!$result2 === true) {
                $messages .= "\nInvalid Query\n".mysqli_error( $conexion )."\nQUERY2:".$query2;
            } else {
    
                $query3  = "";
                $query3 .= "SET autocommit = 0 ";
    
                $result3 = mysqli_query( $conexion, $query3);
    
                if (!$result3 === true) {
                    $messages .= "\nInvalid Query\n".mysqli_error( $conexion )."\nQUERY3:".$query3;
                    f_RollBack();
                } else {
    
                    $query4  = "";
                    $query4 .= "DELETE FROM records ";
                    $query4 .= " WHERE recID = ".$recID."   ";
    
                    $result4 = mysqli_query( $conexion, $query4);
    
                    if (!$result4 === true) {
                        $messages .= "\nInvalid Query\n".mysqli_error( $conexion )."\nQUERY4:".$query4;
                        f_RollBack();
                    } else {
    
                        $rows4 = mysqli_affected_rows($GLOBALS["___mysqli_ston"]);
    
                        if ($rows4 < 1) {
                            $messages .= "\nSelected Record could not be DELETED.\nQUERY4:".$query4;;
                            f_RollBack();
                        } else {
    
                            $query5  = "";
                            $query5 .= " COMMIT ";
    
                            $result5 = mysqli_query( $conexion, $query5);
    
                            if (!$result5 === true) {
                                $messages .= "\nInvalid Query\n".mysqli_error( $conexion )."\nTransaction has not been COMITTED."."\nQUERY5:".$query5;
                            }//if (!$result5 === true) COMMIT
                        }//if ($rows4 == -1) 
                    }//if (!$result4 === true)
                }//if ($rows3 < 1)
            }//if (!$result3 === true)
        }//if (!$result2 === true)
    }//if (!$result1 === true)
    
    
    mysqli_close($GLOBALS["___mysqli_ston"]);
    
    if ($messages != "") {
        $returnVars["retorno"]  = "Error";
        $returnVars["extra"]        = $messages;
    } else {
        $returnVars["retorno"]  = "OK";
        $returnVars["extra"]        = "";
    }//if ($messages != "")
    
    $returnString = http_build_query($returnVars);
    
    //send variables back to Flash
    echo $returnString;
     ?>
    

    如果有人能够找出我做错了什么,我会非常感激。

1 个答案:

答案 0 :(得分:0)

我之前提供了这个并且被投票了。我认为这个框架可以帮助你,所以我会再次冒险。大声笑。请注意,我希望它通过提供SIMPLE调试方法帮助您解决问题(只需将false更改为true ...并且调试已启用!)。

使用这个系统是将设置信息(#Sample Execution之前的所有内容)放在页面顶部,并在页面底部放置#个函数......然后有几个例子说明如何“从这一点开始,使用“这两个函数来获取两行数据(一个用于定义查询,一个用于运行查询)”。结果是使用您请求的数据更改DB或数组。希望能帮助到你。我们每天都在使用它。

define('DEBUG', false);
define('CLIDISPLAY', false);
if (CLIDISPLAY) {
    define('PRE', '');
    define('PRE_END', '');
} else {
    define('PRE', '<pre>');
    define('PRE_END', '</pre>');
}
require_once("../dbconnect.php");
$DBLink = new mysqli($VARDB_server, $VARDB_user, $VARDB_pass, $VARDB_database, $VARDB_port);
if ($DBLink->connect_errno) {
    printf(PRE . "Connect failed: %s\n" . PRE_END, $DBLink->connect_error);
    exit();
}

# Sample execution
$Query = "select * from vicidial_users where user='6666' and active='Y' limit 1";
$Records = GetData($DBLink, $Query);
print_r($Records[0]); // Single record return access via [0] to access a field named "id": $Records[0]['id']
// Multiple record return access via array walking
foreach ($Records as $Record) {
    print_r($Record);
}
$Query = "update vicidial_users set active='Y' where user='6666' limit 1";
UpdateData($DBLink, $Query);

#Functions

function GetData($DBLink, $Query) {
    if (DEBUG) {
        echo PRE . "Query: $Query\n" . PRE_END;
    }
    if ($Result = $DBLink->query($Query)) {
        if (DEBUG) {
            printf(PRE . "Affected rows (Non-Select): %d\n" . PRE_END, $DBLink->affected_rows);
        }
        while ($Record = $Result->fetch_assoc()) {
            $ReturnData[] = $Record;
        }
        return $ReturnData;
    } else {
        if (DEBUG) {
            printf(PRE . "Errormessage: %s\n", $DBLink->error);
            printf("Affected rows (Non-Select): %d\n", $DBLink->affected_rows);
            echo "No Records Returned\n" . PRE_END;
        }
        return false;
    }
}

function UpdateData($DBLink, $Query) {
    if (DEBUG) {
        echo PRE . "Query: $Query\n" . PRE_END;
    }
    if ($Result = $DBLink->query($Query)) {
        if (DEBUG) {
            printf(PRE . "%s\n", $DBLink->info);
            printf("Affected rows (Non-Select): %d\n" . PRE_END, $DBLink->affected_rows);
        }
        return;
    } else {
        if (DEBUG) {
            printf(PRE . "Errormessage: %s\n", $DBLink->error);
            printf("Affected rows (Non-Select): %d\n", $DBLink->affected_rows);
            echo "No Records Returned\n" . PRE_END;
        }
        return;
    }
}

显然,dbconnect.php及其加载的变量可以替换为现有版本。要进行故障排除:将调试更改为TRUE而不是FALSE。然后查询将溢出到屏幕,您可以将其直接复制/粘贴到您的数据库中,看看结果是否符合预期。请注意,对于BEST结果,在执行此操作时仍有一些项目需要验证(如果运行相同查询时php脚本的结果与您的结果不同,则只需要其中一些项目):

  1. 确保您所在的数据库中已加载到您的凭据中
  2. 确保使用与运行的脚本相同的IP输入数据库作为具有相同密码的用户。这可能需要在php服务器上使用mysql客户端从命令行访问数据库,以确保您的凭据和权限与php脚本相同。
  3. CLIDISPLAY常量仅用于从CLI而不是在网页上执行php(使烦人的条目消失,但这些在html中非常有用)。