簡體   English   中英

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

[英]mysqli_query returns 0 rows (weird behaviour)

從Flash Actionscript應用程序中調用此非常簡單的方法,旨在僅刪除一條記錄。 這是一個非常大的應用程序,包含1000多個腳本,其中許多腳本成功使用了相同的架構...但是這個腳本拒絕像其他腳本那樣運行。

為了簡單起見,我已經清除了部分代碼,對此沒有任何意義,正如我之前說過的,它非常簡單(如您在代碼中所見):

  1. 檢查記錄是否存在。
  2. 啟動一個MySql事務(START TRANSACTION)
  3. 刪除所需的記錄
  4. 刪除/更新一些其他相關信息(此代碼中省略)
  5. 如果一切正常,則提交交易

好了,問題如下:

  • 如果我按代碼所示運行腳本,則在第一個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;
 ?>

如果有人能發現我在做什么錯,我將非常感激。

我已經提供了這個,並被否決了。 我認為該框架可能會對您有所幫助,因此我將再次冒險。 大聲笑。 請注意,我希望它通過提供一種簡單的調試方法(將false更改為true ...並打開調試!)來幫助您解決問題。

此系統的用途是將設置信息(#Sample Execution之前的所有內容)放在頁面頂部,並將#函數放在頁面底部...然后有幾個示例說明如何“使用”這些信息從這一點開始,有兩個函數用兩行來獲取數據(一個用於定義查詢,一個用於運行查詢)。 結果是數據庫或包含您請求的數據的陣列發生了更改。 希望能幫助到你。 我們每天都在使用它。

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及其加載的變量可以替換為現有版本。 解決方法:將debug更改為TRUE而不是FALSE。 然后查詢將溢出到屏幕上,您可以將其直接復制/粘貼到數據庫中,並查看結果是否符合預期。 請注意,為獲得最佳結果,在執行此操作時,您仍有幾項要驗證(其中某些項只有在運行相同查詢時php腳本獲得的結果與您不同時才是必需的):

  1. 確保您位於要加載到憑據中的數據庫中
  2. 確保以與運行腳本相同的用戶名和密碼輸入數據庫。 這可能需要使用php服務器上的mysql客戶端從命令行訪問數據庫,以確保您的憑據和權限與php腳本相同。

CLIDISPLAY常量僅用於從CLI而不是在網頁上執行php(使煩人的條目消失,但是在html中它們非常有用)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM