- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用一个一直在处理我的代码的函数,现在我正在慢慢地从 MySQLi 转向 PDO - 这个函数应该“简单地”采用 SQL 语句和变量数组并设置准备好的语句,然后执行它并返回一个带有“成功/失败”代码的数组,然后返回lastInsertId。
到目前为止,该函数一直工作得很好,考虑到我收到的错误(而且我是 PDO 新手),我想知道问题出在哪里。
首先,函数本身非常良性(在其他地方定义的常量)
function dbConnect(){
try {
if(!defined('PDO::ATTR_DRIVER_NAME')){
debugPrint('Error: PDO unavailable');
return false;
}
$dsn = 'mysql:host=' . DB_SERVER . ';dbname=' . DB_NAME . ';charset=UTF8';
$opt = [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
];
$db = new PDO($dsn, DB_USER, DB_PASS, $opt);
return $db;
} catch (PDOException $e) {
debugPrint($e->getMessage());
return false;
}
}
function dbInsert($sql, $param){
$ret = [];
if(!$pdo = dbConnect()){
$ret[] = 1;
return $ret;
}
if(!$stmt = $pdo->prepare($sql){
echo $pdo->errorInfo();
$ret[] = 1;
return $ret;
}
if(!$stmt->execute($param)){
echo $pdo->errorInfo();
$ret[] = 1;
return $ret;
} else {
$ret[] = 0;
$ret[1] = $pdo->lastInsertId();
return $ret;
}
我正在编写代码,该代码只是检查电子邮件地址是否出现在表中,如果没有出现,则将其插入。我在我的应用程序中经常进行此检查,大约 50% 的情况下提供的电子邮件将是现有条目。
$sql = 'insert into customer (email) select :email from DUAL where not exists (select 1 from customer where email = :email)';
$bind = [':email' => 'user@bogus.org'];
这是迄今为止我见过的最简洁的方法,是对数据库的单个调用并使用准备好的语句。但是,我收到 PDO 错误“参数号无效”和堆栈跟踪错误。我已经打开了 MySQL 日志记录,看起来准备工作没问题...
Prepare insert into customer (email) select ? from DUAL where not exists (select 1 from customer where email = ?)
...所以我只能认为是绑定(bind),考虑到参数错误的数量,这是有道理的,但异常似乎来自执行:
PHP Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number in {filename}:78
Stack trace:
#0 {filename}:78: PDOStatement->execute(Array)
#1 {callingFile(33)}: dbInsert('insert into cus...', Array)
#2 {main}
thrown in {filename} on line 78
由于我是 PDO 领域的新手,并且渴望学习,因此我想找出应该在哪里解决这个问题。
我很喜欢 PDO 的功能,我希望这不是一个需要解决的太大问题,但目前我不知道为什么会抛出这个错误。我确实想知道是否是因为我使用了“1”
注意:1 我知道我可以使电子邮件在表中唯一,但这意味着 $pdo->execute 返回非零,使我的函数返回非零(错误)(至少在我看来)这并不完全正确。
注意:2 我也知道我可以先检查表格以查看电子邮件是否存在,然后将其插入(如果不存在):但是,我不确定这是最好的做事的方式(并且由于我当前正在更新的代码就是这样做的,所以我认为将其进行 PDO 处理,并且可能对 SQL 调用本身更加聪明)。
注意:3我还将 SQL 语句更改为以下内容:
$sql = 'insert ignore into customer (email) values (:email)';
$bind = [':email' => 'user@bogus.org'];
这是“好的”,但是如果存在现有电子邮件,则收件人表中的自动递增主键会跳过(再次尝试保持一切干净、简单和逻辑),我真的不想破解这个通过附加一个(慢)语句更改表以将 auto_increment 设置为 1
最佳答案
1) 在函数 dbInsert
中,您错过了 if
语句的最后一个括号:
if (!$stmt = $pdo->prepare($sql)) {...}
<小时/>2)如
PDO::prepare官方文档所述:
You cannot use a named parameter marker of the same name more than once in a prepared statement, unless emulation mode is on.
例如不允许在 sql 语句中多次使用 :email
,除非激活 ATTR_EMULATE_PREPARES
选项:
PDO::ATTR_EMULATE_PREPARES => TRUE
如果不这样做,您将收到与您所提供的完全相同的错误。
因此,要么应用上面的建议,要么保持模拟不变(例如 FALSE
)并使用两个不同的命名参数标记(:email1
和 :电子邮件2
):
$email = 'user@bogus.org';
$sql = 'insert into customer (email) select :email1 from DUAL where not exists (select 1 from customer where email = :email2)';
$bind = [
':email1' => $email,
':email2' => $email,
];
或者您可以使用问号 (?) 参数标记:
$email = 'user@bogus.org';
$sql = 'insert into customer (email) select ? from DUAL where not exists (select 1 from customer where email = ?)';
$bind = [
1 => $email,
2 => $email,
];
作为一个非常好的资源,我向您推荐 this教程。
关于mysql - PDO 准备语句 "Invalid Parameter Number",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48434272/
从 angular 5.1 更新到 6.1 后,我开始从我的代码中收到一些错误,如下所示: Error: ngc compilation failed: components/forms/utils.
我正在学习 Typescript 并尝试了解类型和接口(interface)的最佳实践。我正在玩一个使用 GPS 坐标的示例,想知道一种方法是否比另一种更好。 let gps1 : number[];
type padding = [number, number, number, number] interface IPaddingProps { defaultValue?: padding
这两种格式在内存中保存结果的顺序上有什么区别吗? number = number + 10; number += 10; 我记得一种格式会立即保存结果,因此下一行代码可以使用新值,而对于另一种格式,
在 Python 匹配模式中,如何匹配像 1 这样的文字数字在按数字反向引用后 \1 ? 我尝试了 \g用于此目的的替换模式中可用的语法,但它在我的匹配模式中不起作用。 我有一个更大的问题,我想使用一
我的源文件here包含 HTML 代码,我想将电话号码更改为可在我的应用程序中单击。我正在寻找一个正则表达式来转换字符串 >numbernumber(\d+)$1numbernumber<",我们在S
我们有一个包含 2 个字段和一个按钮的表单。我们想要点击按钮来输出位于 int A 和 int B 之间的随机整数(比如 3、5 或 33)? (不需要使用 jQuery 或类似的东西) 最佳答案 你
我收到以下类型错误(TypeScript - 3.7.5)。 error TS2345: Argument of type '(priority1: number, priority2: number
只想创建简单的填充器以在其他功能中使用它: function fillLine(row, column, length, bgcolor) { var sheet = SpreadsheetApp
我有一个问题。当我保存程序输出的 *.txt 时,我得到以下信息:0.021111111111111112a118d0 以及更多的东西。 问题是: 这个数字中的“d0”和“a”是什么意思? 我不知道“
首先:抱歉标题太长了,但我发现很难用一句话来解释这个问题;)。是的,我也四处搜索(这里和谷歌),但找不到合适的答案。 所以,问题是这样的: 数字 1-15 将像这样放在金字塔中(由数组表示):
我想从字符串中提取血压。数据可能如下所示: text <- c("at 10.00 seated 132/69", "99/49", "176/109", "10.12 I 128/51, II 1
当尝试执行一个简单的 bash 脚本以将前面带有 0 的数字递增 1 时,原始数字被错误地解释。 #!/bin/bash number=0026 echo $number echo $((number
我有一个类型为 [number, number] 的字段,TypeScript 编译器(strict 设置为 true)出现问题,提示初始值值(value)。我尝试了以下方法: public shee
你能帮我表达数组吗:["232","2323","233"] 我试试这个:/^\[("\d{1,7}")|(,"\d{1,7}")\]$/ 但是这个表达式不能正常工作。 我使用 ruby(rail
这个问题在这里已经有了答案: meaning of (number) & (-number) (4 个回答) 关闭6年前. 例如: int get(int i) { int res = 0;
我正在考虑使用 Berkeley DB作为高度并发的移动应用程序后端的一部分。对于我的应用程序,使用 Queue对于他们的记录级别锁定将是理想的。但是,如标题中所述,我需要查询和更新概念建模的数据,如
我正在尝试解决涉及重复数字的特定 JavaScript 练习,为此我需要将重复数字处理到大量小数位。 目前我正在使用: function divide(numerator, denominator){
我有这个数组类型: interface Details { Name: string; URL: string; Year: number; } interface AppState {
我们正在使用 Spring 3.x.x 和 Quartz 2.x.x 实现 Web 应用程序。 Web 服务器是 Tomcat 7.x.x。我们有 3 台服务器。 Quartz 是集群式的,因此所有这
我是一名优秀的程序员,十分优秀!