PHP mySQLi prepare失败,列“?”重复

PHP mySQLi prepare失败,列“?”重复,php,mysql,mysqli,Php,Mysql,Mysqli,我正试图用mysqli准备一份声明 $stmt = $mysqli->prepare("INSERT HIGH_PRIORITY INTO `user` (`FirstName`, `LastName`, `Department`, `Email`) SELECT * FROM (SELECT ?,?,?,?) AS tmp WHERE NOT EXISTS ( SELECT `Email` FROM `user` WHERE `Email` = ? ) LIMIT 1;"); if (!

我正试图用mysqli准备一份声明

$stmt = $mysqli->prepare("INSERT HIGH_PRIORITY INTO `user` (`FirstName`, `LastName`, `Department`, `Email`) SELECT * FROM (SELECT ?,?,?,?) AS tmp WHERE NOT EXISTS ( SELECT `Email` FROM `user` WHERE `Email` = ? ) LIMIT 1;");
if (!$stmt) {
    printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
    die;
}

$statementReturnCode = $stmt->bind_param("sssss", $ssoFirstName, $ssoLastName, $ssoDepartment, $ssoEmail, $ssoEmail);
if (!$statementReturnCode) {
    printf('errno: %d, error: %s', $stmt->errno, $stmt->error);
}

$stmt->execute();
$stmt->close();
运行此操作时,我收到以下错误:

errno: 1060, error: Duplicate column name '?'
过去我可以用这种方式绑定,但我从未尝试在查询电子邮件中的不同位置绑定同一列两次

如何在两个不同的位置对电子邮件使用相同的值,或者这是一个不同的问题

要澄清如何处理此查询,请执行以下操作:

此查询将经常运行。如果用户表中已存在该用户,则不应尝试插入。如果用户不存在,则应将该用户添加到用户表中

用户表有一个自动递增的UserID字段。如果尝试插入,由于唯一约束,将不会添加用户,但即使插入未发生,自动增量也会添加1。这个WHERE NOT EXISTS查询试图缓解这个问题

示例用法:

INSERT INTO `user` (
    `user`.`FirstName`, 
    `user`.`LastName`, 
    `user`.`Department`, 
    `user`.`Email`)
SELECT * FROM (SELECT 'John', 'Doe', 'Marketing', 'John.Doe@mycorp.com') AS tmp
WHERE NOT EXISTS (
    SELECT `user`.`Email` 
    FROM `user` 
    WHERE `user`.`Email` = 'John.Doe@mycorp.com'
) LIMIT 1;

我已经测试了这个查询,它按照我的预期工作。我遇到的问题是如何使用php将此查询正确地更改为一个准备好的语句。

列名不是字符串文本,您不需要绑定列名

$stmt = $mysqli->prepare(sprint("INSERT HIGH_PRIORITY INTO `user` (`FirstName`, `LastName`, `Department`, `Email`) SELECT * FROM (SELECT '%s', '%s', '%s', '%s') AS tmp WHERE NOT EXISTS ( SELECT `Email` FROM `user` WHERE `Email` = ? ) LIMIT 1;"), $ssoFirstName, $ssoLastName, $ssoDepartment, $ssoEmail);
if (!$stmt) {
    printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
    die;
}

$statementReturnCode = $stmt->bind_param("s", $ssoEmail);
if (!$statementReturnCode) {
    printf('errno: %d, error: %s', $stmt->errno, $stmt->error);
}

列名不是字符串文字,不绑定列名

$stmt = $mysqli->prepare(sprint("INSERT HIGH_PRIORITY INTO `user` (`FirstName`, `LastName`, `Department`, `Email`) SELECT * FROM (SELECT '%s', '%s', '%s', '%s') AS tmp WHERE NOT EXISTS ( SELECT `Email` FROM `user` WHERE `Email` = ? ) LIMIT 1;"), $ssoFirstName, $ssoLastName, $ssoDepartment, $ssoEmail);
if (!$stmt) {
    printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
    die;
}

$statementReturnCode = $stmt->bind_param("s", $ssoEmail);
if (!$statementReturnCode) {
    printf('errno: %d, error: %s', $stmt->errno, $stmt->error);
}

这是不可能做到的。使用PHP的mysqli扩展准备的语句不能用于以下几项:

表名 选择列表中的列 我试图在选择列表中使用无法完成的动态项


这是不可能做到的。使用PHP的mysqli扩展准备的语句不能用于以下几项:

表名 选择列表中的列 我试图在选择列表中使用无法完成的动态项



列名不是字符串文字,不绑定列名子查询中的SELECT语句不绑定列名,只是告诉mySQL要输出什么。示例有效查询选择“Hello Stack Exchange”;列名不是字符串文字,不绑定列名子查询中的SELECT语句不绑定列名,只是告诉mySQL要输出什么。示例有效查询选择“Hello Stack Exchange”;我使用这个insert语句来避免mySQL在每次发现重复项时自动递增。如果在表中找不到用户的电子邮件,则此查询应插入一个名为FirstName、LastName等的新用户。。。因此,这些列不能被忽略。我将用一个例子来更新这个问题。尝试修改代码。。。。但是首先要确保$SSOIRSTNAME、$SSOIRSTNAME、$ssoDepartment和$SSOMail都已正确转义和清除为什么要阻止MySQL自动递增?强迫症问题,你被间隙困扰了?自己检查,而不是在该列上插入+并具有唯一键,这意味着您最终将得到重复项,因为您刚刚打开了并发问题。根据查询被命中的频率,在这种情况下,这可能是一个每天数千次的问题。以这种方式执行查询并具有唯一约束可以解决问题。我暂时转义了源代码,因为它足够可靠,可以处理shibboleth数据,但我仍然希望知道如何处理。我使用这个insert语句避免mySQL在每次发现重复数据时自动递增。如果在表中找不到用户的电子邮件,则此查询应插入一个名为FirstName、LastName等的新用户。。。因此,这些列不能被忽略。我将用一个例子来更新这个问题。尝试修改代码。。。。但是首先要确保$SSOIRSTNAME、$SSOIRSTNAME、$ssoDepartment和$SSOMail都已正确转义和清除为什么要阻止MySQL自动递增?强迫症问题,你被间隙困扰了?自己检查,而不是在该列上插入+并具有唯一键,这意味着您最终将得到重复项,因为您刚刚打开了并发问题。根据查询被命中的频率,在这种情况下,这可能是一个每天数千次的问题。以这种方式执行查询并具有唯一约束可以解决问题。我暂时逃离了源代码,因为它足够可靠,可以处理shibboleth数据,但我仍然想知道如何做到这一点。谁说你不能绑定限制限定符?你选择的不是coluns,而是字符串。我链接到的页面是这样说的,我在选择列表中选择字符串,这也是不允许的,也不能引发这个问题。然后这个页面告诉你垃圾。SQL中完全允许选择字符串。不能像我在上面的问题中尝试的那样,使用准备好的语句选择动态字符串作为列。如果你能用PHP的mysqli找到一种方法,那么请回答这个问题。目前为止,我还没有找到这样的解决方案。对于一个简单的选择,你可以。谁说你不能绑定限制限定符?你没有选择coluns,但是
字符串。我链接到的页面是这样说的,我在选择列表中选择字符串,这也是不允许的,也不能引发这个问题。然后这个页面告诉你垃圾。SQL中完全允许选择字符串。不能像我在上面的问题中尝试的那样,使用准备好的语句选择动态字符串作为列。如果你能用PHP的mysqli找到一种方法,那么请回答这个问题。目前为止,我还没有找到这样的解决方案。只需一个简单的选择,你就可以了。