如果不存在插入数据的复杂php mysqli查询:获取重复的列名'';

如果不存在插入数据的复杂php mysqli查询:获取重复的列名'';,php,mysql,mysqli,Php,Mysql,Mysqli,各位,请检查我的示例代码,并帮助我,我找不到解决方案,在我传递参数的行上不断得到重复的列名,如。 我在查询中总共传递了7个变量。知道有什么问题吗 $SQL = "INSERT INTO wifi (ssid, password, name, surname) SELECT * FROM(SELECT ?, ?, ?, ?) AS tmp WHERE NOT EXISTS (SELECT ssid,name,surname FROM wifi WHERE ssid=? AND n

各位,请检查我的示例代码,并帮助我,我找不到解决方案,在我传递参数的行上不断得到重复的列名,如。 我在查询中总共传递了7个变量。知道有什么问题吗

$SQL = "INSERT INTO wifi (ssid, password, name, surname) SELECT *        
FROM(SELECT ?, ?, ?, ?) AS tmp WHERE NOT EXISTS (SELECT 
ssid,name,surname FROM wifi WHERE ssid=? AND name=? AND 
surname=?) LIMIT 1;";


if ($stmt = $mysqli->prepare($SQL)) {
$stmt->bind_param("sssssss", $ssid, $password, $name, $surname,$ssid, $name, $surname);
$stmt->execute();
echo $SQL;
}

if ( false===$stmt ) {

   die('prepare() failed: ' . htmlspecialchars($mysqli->error));
 }
好的,我知道这有点复杂,但这个查询是在mysql服务器上运行的。我只是在PHP中遇到问题,因为它返回prepare()失败:重复的列名“?”

谢谢

试试这个:

ALTER TABLE wifi ADD UNIQUE INDEX idx (ssid,name,surname);

INSERT IGNORE INTO wifi (ssid, password, name, surname) VALUES (?, ?, ?, ?) 
$SQL = "INSERT INTO wifi (ssid, password, name, surname) 
        SELECT ?, ?, ?, ? FROM DUAL 
        WHERE NOT EXISTS (
            SELECT *
            FROM wifi 
            WHERE ssid=? AND name=? AND surname=?)";
DUAL
是一个虚拟表名,当您不需要访问实际表时,可以使用它。将占位符放在主
SELECT
而不是子查询中似乎可以避免占位符问题

另一种方法是在这些列上创建唯一索引:

CREATE UNIQUE INDEX ssid_name_surname ON wifi (ssid, name, surname);
然后您可以使用:

$SQL = "INSERT IGNORE INTO wifi (ssid, password, name, surname)
        VALUES (?, ?, ?, ?)";
如果要更新密码(如果密码已存在),请在重复密钥更新时使用
,而不是
插入忽略

$SQL = "INSERT INTO wifi (ssid, password, name, surname)
        VALUES (?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE password = VALUES(password)";

为什么不在
(ssid、姓名、姓氏)
上添加一个唯一的索引呢。然后你可以使用
INSERT IGNORE
,如果它们已经有一行,它会自动跳过。看起来
prepare()
没有意识到你可以使用
SELECT
列表中的表达式,所以它认为这些是列名而不是占位符。我不确定如何完成,我没有那么丰富的经验,但我想知道这有什么问题。。我不知道为什么prepare()不能识别?marks,我在其他教程中也这么做了。正如我所说,它看起来像是
prepare()
中的一个限制,它不允许您在查询的该部分替换占位符。占位符只允许在允许表达式的地方使用,而不允许在SQL需要表名或列名的地方使用。它似乎对
SELECT
列表感到困惑。他在调用
prepare()
时出错,而不是
bind_param()
不工作,我得到相同的prepare()失败:重复列名“?”我不使用INSERT IGNORE,因为我不知道如何在mysql服务器中重新组织表。。我必须以某种方式改变这些列吗?但是让我试一下,谢谢你!我已经按照你的建议创建了唯一索引,它正在工作!非常感谢你,伙计!嘿,我还有一个问题,如果发现相同的ssid、名称和姓氏,我不想替换数据库中的项,但是如果使用现有的ssid、名称和姓氏传递不同的密码,我想替换现有行中的密码!太复杂了吗?太好了,谢谢!仅应在重复的密钥更新密码=“some_value”上写入,而不应在VALUES()部分写入。。