【问题标题】:Unable to insert new data into MySQL database after deleting an entry using PHPMyAdmin使用 PHPMyAdmin 删除条目后无法将新数据插入 MySQL 数据库
【发布时间】:2012-07-14 16:52:31
【问题描述】:

我在第一次尝试时设法运行以下代码插入到我的表中。然后,我在 PHPMyAdmin 中删除了该行以进一步测试我的代码。我还注意到它在第一次尝试时没有被删除。只有经过几次尝试。这可能是因为我在完成查询后没有将 $pdoHandle 设置为 NULL。

然后,不幸的是我无法在后续运行中插入新行。我什至尝试更改输入值并利用我无法插入新行。以下是我的 PHP 代码:

public function CreateNewCustomer($userId,$password,$name,$email)
{
    $userId = filter_var($userId,FILTER_SANITIZE_STRING);
    $password = filter_var($password,FILTER_SANITIZE_STRING);
    $password = sha1($password);
    $name = filter_var($name,FILTER_SANITIZE_STRING);
    $email = filter_var($email,FILTER_SANITIZE_EMAIL);

    do{
        $customerId = hexdec(bin2hex(openssl_random_pseudo_bytes(4,$isStrong)));
        echo $customerId;
        $result = $this->connObject->exec("SELECT COUNT(id) FROM customer_tbl WHERE id=$customerId");
        var_dump($result);
    }while($result>0);

    $statement = $this->connObject->prepare("INSERT INTO customer_tbl (id,name,email) VALUES ($customerId,:name,:email)");
    $result = $statement->execute(array(':name'=>$name,':email'=>$email ));
    var_dump($result);

    $statement = $this->connObject->prepare("INSERT INTO login_tbl (username,password,customer_id) VALUES (:userName,PASSWORD(:password),$customerId)");
    $result = $statement->execute(array(':userName'=>$userId,':password'=>$password ));
    var_dump($result);
}

我使用下面的代码来访问上面的方法。

function Test($userName,$password,$name,$email)
{
try
{
    $dbConnect = new DbConnect();
    $pdoHandle = $dbConnect->Connect();
    $userAccess = new UserAccess($pdoHandle);
    $userAccess->CreateNewCustomer($userName,$password,$name,$email);
}
catch(PDOException $e)
{
    $pdoHandle = null;
    var_dump($e);
}
$pdoHandle = null;
}

Test('tester','password','TestX','test@example.com');

结果的 var_dump 总是假的。

我的代码有问题还是数据库有问题?

更新/解决方案:

我刚刚阅读了 PDO::exec() 上的 PHP 文档,其中一位用户提供的注释提到您不能使用任何 SELECT 语句(即使上面只返回计数值)和任何可能的语句返回一行。 PDO::exec() 的返回值是受影响的行数(整数),所以不能使用 PDOStatement::closeCursor() 来解决。即使我设置了 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=>true,它仍然不起作用。

所以,不要对任何 SELECT 使用 PDO::exec()。我将代码更改为 PDO::query() ,如下所示,

   do{
        $customerId = hexdec(bin2hex(openssl_random_pseudo_bytes(4,$isStrong)));
        $statement = $this->connObject->query("SELECT COUNT(id) FROM customer_tbl WHERE id=$customerId");
        $statement->execute();
    }while($statement->fetchColumn(0)>0);

希望这对任何寻求类似问题的解决方案的人有所帮助,并始终记住首先阅读 PHP 文档,包括用户的贡献。

【问题讨论】:

  • 我确实试图四处寻找类似问题的答案,但找不到任何问题,而且大多数问题都是使用旧的“mysql_*”函数。
  • 我想你得到一个错误(因为返回值为假)。我看不到明显的错误。我建议在执行语句后输出以下内容(以获取更多错误信息):$arr = $statement->errorInfo(); print_r($arr);
  • 您好 Bernhard,看起来有一个未缓冲的查询处于活动状态。以下是错误信息:“在其他无缓冲查询处于活动状态时无法执行查询。考虑使用 PDOStatement::fetchAll()。或者,如果您的代码仅针对 mysql 运行,您可以通过设置 PDO:: 来启用查询缓冲: MYSQL_ATTR_USE_BUFFERED_QUERY”。有缓冲和无缓冲有什么区别?
  • 我不是 PDO 专家,但我认为您可以配置在创建句柄时是否使用缓冲 $dbh = new PDO(’mysql:host=localhost;dbname=test’, ‘root’, ” ,array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)) 我猜问题是您的 while 循环(不读取所有内容/不关闭连接/语句)当您从数据库中获取数据但不读取所有返回的数据时,它有一些事情要做。详情请见PDO documentation
  • 非常感谢 Bernhard 指出了正确的方向。看起来我需要更多地研究 PDO::MYSQL 属性。再次感谢。

标签: php mysql pdo phpmyadmin


【解决方案1】:

也许不是答案,但如果您看不到明显的错误,可以执行以下操作:

如果执行返回 false,您可以通过以下方式获取更多信息关于发生的错误:

$arr = $statement->errorInfo(); 
print_r($arr);

或者你可以设置不同的error reporting modes(例如抛出异常而不是默认的静默模式):

$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

这应该可以帮助您找到“真正的”错误。

事实证明(请参阅下面的问题 cmets),在这种情况下,真正的错误是:

“当其他无缓冲查询处于活动状态时,无法执行查询。 考虑使用 PDOStatement::fetchAll()。或者,如果您的代码 只会针对mysql运行,您可以启用查询 通过设置 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 进行缓冲"

在这种情况下,您有 2 个选项:

您可以设置使用缓冲查询的选项

$dbh = new PDO(’mysql:host=localhost;dbname=test’, ‘root’, ” ,array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)) 

或更改您的代码并关闭打开的游标(可能取决于您使用的数据库驱动程序)。你应该经常阅读documentation,它涵盖了很多默认问题。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我假设该方法在 UserAccess 类中,并且您传入的连接设置为本地 $this->connObject

    我怀疑在您删除记录后,在您有趣的 do-while 循环中使用 select 语句将 $customerId 设置为 null。如果数据库中的 id 列是非空主键字段,并且您尝试插入显式空值,它将失败。

    此外,无需继续将您的数据库连接设置为空……这不是 C 语言,并且连接不是持久的(除非您明确声明它们)。

    【讨论】:

    • 嗨,雷,感谢您的回答。 $customerId 未设置为 null。看起来有一个无缓冲的查询仍然处于活动状态。顺便说一句,感谢您指出数据库连接设置为空。
    • 在 do..while 循环中,我使用 auto_increment 随机生成一个唯一 ID。 do..while 循环是为了确保随机生成的 id 不存在于表中。如果存在,则重新创建随机 id。
    猜你喜欢
    • 1970-01-01
    • 2016-10-15
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    相关资源
    最近更新 更多