【问题标题】:PHP MySQL Insert INTO...ON Duplicate Key Update WherePHP MySQL Insert INTO...ON Duplicate Key Update Where
【发布时间】:2020-03-10 22:55:56
【问题描述】:

我需要在票表中不存在行时插入和/或在行存在时更新 1 个查询。

我尝试了以下方法,它没有添加新记录,也没有增加现有记录。

$query_upsert = mysqli_query($mysqli, 
    "INSERT INTO tickets (
        ticket_companyname,
        ticket_ordernumber,
        ticket_datetimedeliverydate,
        ticket_ritech,
        ticket_ticketstatus
    )
    SELECT 
        nextgenorder_companyname, 
        nextgenorder_ordernumber,
        nextgenorder_deliverydate,
        '$ticket_ritech',
        '$ticket_ticketstatus'
    FROM nextgenorders2 
    WHERE 
        nextgenorder_companyname LIKE CONCAT(SUBSTRING_INDEX('$nextgenorder_companyname', ' ', 1),'%') 
        AND nextgenorder_deliverydate='$nextgenorder_deliverydate'
    ON DUPLICATE KEY UPDATE,
         ticket_companyname='$ticket_companyname',
         ticket_ordernumber='$ticket_ordernumber',
         ticket_datetimedeliverydate='$ticket_datetimedeliverydate',
         ticket_ritech='$ticket_ritech',
         ticket_ticketstatus='$ticket_ticketstatus'
    WHERE
        ticket_companyname LIKE CONCAT(SUBSTRING_INDEX('$nextgenorder_companyname', ' ', 1),'%') 
        AND ticket_datetimedeliverydate='$nextgenorder_deliverydate'
    )"
);

你可以在 upsert 查询中使用 WHERE 子句吗?我有所有错误,我没有收到任何错误。

请帮忙。

谢谢,

【问题讨论】:

  • 警告:使用mysqli 时,您应该使用parameterized queriesbind_param 将任何数据添加到您的查询中。 请勿使用字符串插值或连接来完成此操作,因为您创建了严重的SQL injection bug切勿$_POST$_GET任何类型的数据直接放入查询中,如果有人试图利用您的错误,这可能会非常有害。
  • 这个查询由于冗长而很难阅读。您可以将显示的字段数量减少到更小的相同版本吗?如果您没有收到任何错误,您确定要检查它们吗?他们被记录了吗?尝试运行查询"SELECT this should not work",如果没有出现错误,则必须先修复它。
  • 我马上就做
  • 去掉查询末尾ON DUPLICATE KEY UPDATE ...之后的WHERE子句。这不是有效的语法。 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WHERE ticket_companyname LIKE CONCAT(SUBSTRING_INDEX('$nextgenorder_com' at line 58
  • 内部SELECT 是否独立工作?

标签: php mysql sql sql-insert on-duplicate-key


【解决方案1】:

查询的问题和可能的改进:

  • 它有两个WHERE 子句:你只想要一个,它应该出现在SELECT 子句之后

  • 您对 SQL 注入持开放态度,您应该使用绑定参数

  • 你不需要重复赋值右侧的参数:相反,你可以使用VALUES语法

  • 另外我认为您试图更新 ON DUPLICATE KEY 子句中的太多字段,我删除了其中一些并让那些我认为相关的字段(本质上,您不需要更新列用于检查冲突)

考虑:

INSERT INTO tickets (
    ticket_companyname,
    ticket_ordernumber,
    ticket_datetimedeliverydate,
    ticket_ritech,
    ticket_ticketstatus
)
SELECT 
    nextgenorder_companyname, 
    nextgenorder_ordernumber,
    nextgenorder_deliverydate,
    ?,                          --> query parameter for "ticket_ritech"
    ?,                          --> ... "ticket_ticketstatus"
FROM nextgenorders2 
WHERE 
    nextgenorder_companyname 
        LIKE CONCAT(SUBSTRING_INDEX(?, ' ', 1),'%') --> ... "nextgenorder_companyname"
    AND nextgenorder_deliverydate = ?               --> ... "nextgenorder_deliverydate"
ON DUPLICATE KEY UPDATE,
    ticket_ritech = VALUES(ticket_ritech)
    ticket_ticketstatus = VALUES(ticket_ticketstatus)

【讨论】:

  • 他们使用的是 mysqli_,而不是 PDO。
  • @FunkFortyNiner:啊,是的。我改变了位置参数。谢谢!
  • 插入部分有效,但更新无效。如果我运行查询,它会插入重复记录而不是更新现有记录。
  • 这在将序列号列更改为唯一列后有效。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
  • 2016-10-29
  • 2017-02-21
  • 1970-01-01
相关资源
最近更新 更多