PDO mysql:如何知道插入是不是成功
Posted
技术标签:
【中文标题】PDO mysql:如何知道插入是不是成功【英文标题】:PDO mysql: How to know if insert was successfulPDO mysql:如何知道插入是否成功 【发布时间】:2010-12-12 07:45:09 【问题描述】:$stmt->bindParam(':field1', $field1, PDO::PARAM_STR);
$stmt->bindParam(':field2', $field2, PDO::PARAM_STR);
$stmt->execute();
有没有办法知道它是否插入成功,例如记录是否因为重复而没有插入?
编辑:我当然可以查看数据库,但我的意思是程序化反馈。
【问题讨论】:
【参考方案1】:PDOStatement->execute()
成功时返回 true。还有PDOStatement->errorCode()
可以检查错误。
【讨论】:
怎么看execute()值? 不再这样了,$value = $stmt->execute(); if($value)//trueelse//false 或者你也可以if ($stmt->execute()) //true
PDOStatement->execute()
和PDOStatement->errorCode()
是否完全一致? PDOStatement->errorCode()
有东西但 PDOStatement->execute()
返回 true 时,是否有任何情况?或者当 PDOStatement->execute()
返回 false 但 PDOStatement->errorCode()
什么都没有时?
但是即使没有插入新记录,INSERT IGNORE 也会返回 true【参考方案2】:
尝试查看execute
的返回值,成功时为TRUE
,失败时为FALSE
。
【讨论】:
【参考方案3】:如果使用与当前数据库记录匹配的值执行更新查询,则$stmt->rowCount()
将返回0
,因为没有行受到影响。如果你有一个if( rowCount() == 1 )
来测试成功,你会认为更新失败,但它没有失败但值已经在数据库中,所以没有任何变化。
$stmt->execute();
if( $stmt ) return "success";
当我尝试使用违反的唯一键字段更新记录时,这对我不起作用。查询返回成功,但另一个查询返回旧字段值。
【讨论】:
如果您需要插入记录,最好的方法是这样检查...................... ... ....................if($stmt->execute() && ($stmt->rowCount()>0))
【参考方案4】:
鉴于最推荐的 PDO 错误模式是 ERRMODE_EXCEPTION
,没有直接的 execute()
结果验证将起作用。由于代码执行甚至不会达到其他答案中提供的条件。
所以,在 PDO 中处理查询执行结果有三种可能的场景:
-
表示成功,无需验证。只需保持您的程序流程即可。
要处理意外错误,请保持相同 - 不需要立即处理代码。如果发生数据库错误,则会引发异常,并且会冒泡到站点范围的错误处理程序,最终会导致常见的 500 错误页面。
要处理预期的错误,例如重复的主键,并且如果您有特定的场景来处理此特定错误,请使用
try..catch
运算符。
对于普通的 PHP 用户来说,这听起来有点陌生 - 怎么样,不是为了验证操作的直接结果? - 但这正是异常的工作方式 - 您在其他地方检查错误。一次就好。非常方便。
因此,简而言之:在常规代码中,您根本不需要任何错误处理。保持你的代码不变:
$stmt->bindParam(':field1', $field1, PDO::PARAM_STR);
$stmt->bindParam(':field2', $field2, PDO::PARAM_STR);
$stmt->execute();
echo "Success!"; // whatever
成功时它会告诉你,出错时它会显示你的应用程序在这种情况下显示的常规错误页面。
只有在你有处理场景而不是仅仅报错的情况下,把你的insert语句放在try..catch
操作符中,检查是否是你预期的错误并处理;或者 - 如果错误有任何不同 - 重新抛出异常,以便可以通过站点范围的错误处理程序通常的方式进行处理。下面是我article on error handling with 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!";
在上面的代码中,我们正在检查特定错误以采取一些措施,并为将报告给程序员的任何其他错误(例如没有此类表)重新抛出异常。
再一次 - 只是为了告诉用户“您的插入成功”之类的内容不需要任何条件。
【讨论】:
“成功”是什么意思?这意味着插入了一个新行,还是意味着没有任何错误? 对于 INSERT 查询来说几乎是一样的。 你是对的.. 请你告诉我query()
函数怎么样?我可以对 query()
使用 try-catch 代替 prepared()->execute()
吗?
你不应该首先使用 query() 进行插入。 Insert 表示有输入,inpout 表示应该准备好了。
使用 MySQL,我必须检查 $e->errorInfo[1] == 1062 来验证插入是否失败,因为 $e->getCode() 总是 23000。【参考方案5】:
PDOStatement->execute() 可以抛出异常
所以你可以做的是
try
PDOStatement->execute();
//record inserted
catch(Exception $e)
//Some error occured. (i.e. violation of constraints)
【讨论】:
【参考方案6】:使用 id 作为主键并自动递增
$stmt->execute();
$insertid = $conn->lastInsertId();
即使在第一条记录上,增量 id 也总是大于零,这意味着它总是会返回一个真值,因为 id 大于零意味着 PHP 中的真
if ($insertid)
echo "record inserted successfully";
else
echo "record insertion failed";
【讨论】:
如果我的表中不需要自动递增字段怎么办? 谁催款了?你?使用如此广泛使用的 RESTFul API,自动递增 id 就像是强制性的。 为什么有人没有主要和自动增量或任何其他序列列?如果需要验证方法,请添加任何顺序列。如果此解决方案不适合您,请不要添加。这对我来说很好,我总是使用一些顺序和自动递增的列,所以我总是有办法测试我的查询是否成功。【参考方案7】:你可以测试行数
$sqlStatement->execute( ...);
if ($sqlStatement->rowCount() > 0)
return true;
【讨论】:
对文档的引用总是有帮助的@YourCommonSense。它说“这种行为不能保证适用于所有数据库,不应该依赖于可移植应用程序。”但仅限于首先选择,其次支持 mysql,这是本文的主题。 只需在浏览器的地址栏中输入“pdo rowcount”,然后单击第一个链接。打字比评论少 @crafter 正确。它说 rowCount() 对于SELECT
查询可能是不可靠的(即使在那里,文档也谈到了 multiple 查询)。它没有提到DELETE
、INSERT
或UPDATE
,它们似乎可以正常工作(问题是关于INSERT
查询)。但是,我是 PDO 的新手,如果我错了并且有人有其他参考资料,请在此处写下。我很想看看上面的 3 个命令是否有真正的缺点。以上是关于PDO mysql:如何知道插入是不是成功的主要内容,如果未能解决你的问题,请参考以下文章
$stmt->execute() : 如何知道数据库插入是不是成功?