PDO mysql:如何知道插入是否成功


96

我正在使用PDO插入记录(mysql和php)

$stmt->bindParam(':field1', $field1, PDO::PARAM_STR);
$stmt->bindParam(':field2', $field2, PDO::PARAM_STR);
$stmt->execute();

有没有办法知道它是否成功插入,例如,是否由于重复而没有插入记录?

编辑:当然,我可以查看数据库,但是我的意思是程序反馈。

Answers:


140

PDOStatement->execute()成功返回true。还有PDOStatement->errorCode(),你可以检查错误。


1
您如何看待execute()值?
锦葵

29
不再像这样,$ value = $ stmt-> execute(); 如果($值){//真}其他{//假}
奥拉维尔Waage

23
或者您可以做if ($stmt->execute()) { //true }
Gavin 2014年

2
PDOStatement->execute()PDOStatement->errorCode()彼此完全一致?有什么情况PDOStatement->errorCode()PDOStatement->execute()返回真吗?或何时PDOStatement->execute()返回false但PDOStatement->errorCode()什么都没有?
datasn.io

1
但是,即使未插入新记录,INSERT IGNORE也会返回true
Koffeehaus

24

考虑到PDO最推荐的错误模式是ERRMODE_EXCEPTION直接execute()结果验证将永远无法进行。由于代码执行甚至无法达到其他答案中提供的条件。

因此,存在三种可能的情况来处理PDO中的查询执行结果:

  1. 为了证明成功,不需要验证。保持程序流程顺畅。
  2. 要处理意外错误,请保持不变-无需立即处理代码。如果发生数据库错误,将引发异常,并且该异常将冒泡到整个站点范围的错误处理程序,最终将导致常见的500错误页面。
  3. 要处理预期的错误,例如重复的主键,并且如果您有某种情况要处理此特定错误,请使用try..catch运算符。

对于普通的PHP用户来说,这听起来有些陌生-那是怎么回事,而不是验证操作的直接结果?-但这正是异常的工作原理-您可以在其他地方检查错误。一次就好。非常方便。

简而言之:在常规代码中,您根本不需要任何错误处理。只需按原样保留您的代码:

$stmt->bindParam(':field1', $field1, PDO::PARAM_STR);
$stmt->bindParam(':field2', $field2, PDO::PARAM_STR);
$stmt->execute();
echo "Success!"; // whatever

如果成功,它会告诉您,如果出错,它将向您显示应用程序在这种情况下显示的常规错误页面。

仅当您有其他处理情况而不只是报告错误时,才将插入语句放在try..catch运算符中,检查是否是您期望的错误并进行处理;或-如果错误有任何不同,则- 重新引发异常,以使站点范围的错误处理程序可以按通常方式进行处理。以下是我有关PDO错误处理的文章中的示例代码:

try {
     $pdo->prepare("INSERT INTO users VALUES (NULL,?,?,?,?)")->execute($data);
} catch (PDOException $e) {
    if ($e->getCode() == 1062) {
        // Take some action if there is a key constraint violation, i.e. duplicate name
    } else {
        throw $e;
    }
}
echo "Success!";

在上面的代码中,我们正在检查特定错误以采取某些措施,然后针对将报告给程序员的任何其他错误(例如没有此类表)重新抛出异常。

再说一遍-只是告诉用户“您的插入成功”之类的条件就不需要了。


“成功”是什么意思?这是否意味着插入了新行,或者这意味着没有任何错误?
马丁AJ

对于INSERT查询,它几乎是相同的。
常识

您是对的..请您告诉我有关query()功能的信息吗?我可以使用try-catch query()代替prepared()->execute()吗?
马丁AJ

3
首先,绝对不要使用query()进行插入。插入表示有输入,输入表示有准备。
常识

1
使用MySQL,我必须检查$ e-> errorInfo [1] == 1062以验证插入是否失败,因为$ e-> getCode()始终为23000。–
tronman


9

如果执行更新查询时使用与当前数据库记录匹配的值,$stmt->rowCount()则将返回0,不会影响任何行。如果您if( rowCount() == 1 )要测试成功,您会认为更新没有失败但它的值已经在数据库中,所以失败了,所以没有任何变化。

$stmt->execute();
if( $stmt ) return "success";

当我尝试使用违反的唯一键字段更新记录时,这对我不起作用。该查询返回成功,但另一个查询返回旧的字段值。


3
如果需要插入记录,最好的方法是像这样检查................................. ......... if($stmt->execute() && ($stmt->rowCount()>0))
jave.web 2015年

4

您可以测试行数

    $sqlStatement->execute( ...);
    if ($sqlStatement->rowCount() > 0)
    {
        return true;
    }

回到文档的参考对@YourCommonSense总是有帮助的。它说:“并非所有数据库都可以保证这种行为,便携式应用程序不应该依赖这种行为。”但仅限于首先选择,其次是对mysql的支持,这是本文的主题。
手工艺者

只需在浏览器的地址栏中输入“ pdo rowcount”,然后单击第一个链接即可。它的打字比注释要少
您的常识

1
@crafter正确。它说rowCount()对于SELECT查询可能是不可靠的(甚至在那里,文档也谈到了多个查询)。它说一无所知DELETEINSERT或者UPDATE,这似乎是良好的工作(问题是关于INSERT查询)。但是,我是PDO的新手,如果我错了,并且还有其他参考,请在此处写下。我很想看看上面的3个命令是否有真正的缺点。
StanE

1

使用id作为自动递增的主键

$stmt->execute();
$insertid = $conn->lastInsertId();

即使在第一个记录上,增量id始终大于零,这意味着它将始终为id coz返回大于零的true值,这意味着在PHP中为true

if ($insertid)
   echo "record inserted successfully";
else
   echo "record insertion failed";

如果我不需要表格中的自动递增字段怎么办?
您的常识

谁傻了 您?使用广泛使用的RESTFul API,自动递增ID就像是强制性的。
RBK Rbk

为什么有人没有主增量和自动增量或任何其他序列列?如果需要验证方法,请添加任何连续列。如果此解决方案不适用于您,请不要添加它。对我来说这很好,我总是使用一些顺序和自动递增的列,所以我总是有一种方法来测试我的查询是否成功。
塞缪尔·拉姆赞

0

PDOStatement-> execute()可以引发异常

所以你可以做的是

try
{
PDOStatement->execute();
//record inserted
}
catch(Exception $e)
{
//Some error occured. (i.e. violation of constraints)
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.