首页 > 解决方案 > 重复更新时插入或使用 CASE 的 MariaDB 语法

问题描述

我想对设备进行指纹识别,并将结果与​​会话 ID 一起存储在 MariaDb 中。我正在使用 PDO 驱动程序编写 PHP。我在访问的页面上生成打印客户端,并将 XHR 发布到 storePrint.php 我想更新现有记录或插入新记录(如果它们不存在)。下面是源代码的片段。打印可能已经存在具有不同的会话 ID,并且打印可能会更改而会话不会更改。我想更新 print、sessionId 和 lastVisited 时间戳(我使用十进制 14,4 和 microtime(true),因此不是真正的时间戳,但这是另一个切线。

storePrint.php:

require_once('./library.php');
if(isset($_POST) && !empty($_POST))
{
    $_POST = sanitize($_POST); // Clean up input.
    $from = $_POST['from'];
    $print = $_POST['clientPrint']; // max length = 32 characters
    $sId = $_POST['sessionId']; // max-length = 64 characters
    updatePrint($sId,$print,$from);
}
library.php:

    function updatePrint($id,$print,$from)
    {
        $now = microtime(true);
        $sql = "INSERT INTO prints (print,sessionId,lastUpdated) VALUES (:print,:sid,:lastC) ON DUPLICATE KEY UPDATE print=:print, sessionId = :sId, lastUpdated = :lastV";

        $import = [":print" => $print,":sid" => $id,
        ":lastC" => $now,
        ":sId" => $id];//       ":lastV" => $now,
        $connection = connectToDB();
        $statement = $connection->prepare($sql);
        $result = $statement->execute($import);
        $count = $statement->rowCount();

        if($count > 0)
        {
        }else
        {
            echo 'Failure';
        }

    }

加载文档后在客户端生成打印,并触发 storePrint.php 的 XHR。希望更新记录,或者在该 print OR sessionId 不存在的情况下,创建一个新记录。问题是 print 或 sessionId 都可以更改而另一个更改。我需要找到一种方法(如果可能,使用单个查询) 检查是否存在 print 或 sessionId。如果其中任何一个存在,则更新其他(打印,lastVisited,如果我们找到具有相同 sessionId 的记录,或者 sessionId,lastVisited,如果我们找到匹配的打印)。有人指出,我的桌子设计可能不适合我想做的事情。更新会导致违反完整性约束。所以迷路了......我用自动增量制作了 id Primary,并打印了唯一的和 sessionId 唯一的。请把我推向正确的方向。我尝试使用的其他查询是:

INSERT INTO prints (print, sessionId, lastUpdated) VALUES (:print,:sid,:lastC) CASE WHEN print <> :print THEN :print ELSE print END, last_update = CASE WHEN print <> :print THEN :lastV ELSE lastUpdated END;
INSERT INTO prints (print,sessionId,lastUpdated) VALUES (:print,:sid,:lastC) ON DUPLICATE KEY UPDATE print = CASE print WHEN <> THEN :print, ELSE print END, sessionId = CASE sessionId WHEN <> :sid THEN :sid ELSE sessionId END, lastUpdated=now()

INSERT INTO prints (print, sessionId, lastUpdated) VALUES (:print, :sid, :lastC) ON DUPLICATE KEY UPDATE     lastUpdated = CASE WHEN print <> :print THEN :lastC ELSE lastUpdated END, print = CASE WHEN print <> :print THEN :print ELSE print END

我发现使用 PDO 的准备好的语句和使用 VALUE() 导致我出现语法问题,因为它会转义已经转义的字符串,将它们变成-> VALUES(''88fe273778rs8s...'') ,此时我回到第一个准备好的声明,并来这里寻求指导...... 表结构

表格内容

所以最后,我是重写查询,重新设计表,还是两者兼而有之???

更新:我遇到的实际问题是我的 sessionId 列上的完整性约束违规。我最终遇到了打印匹配WHERE id=1和 sessionId 匹配的冲突WHERE id=14 MySQL 决定它将更新id=1并由于重复的 sessionId 导致完整性约束。 我如何使用CASE其他DELETE匹配的记录行?

标签: phpsyntaxmariadbunique-constraint

解决方案


看来你工作太辛苦了。这不是你想要的吗?

INSERT INTO prints (print,sessionId,lastUpdated)
      VALUES (:print,:sid,:lastC)
      ON DUPLICATE KEY UPDATE
           print = VALUES(print),
           sessionId = VALUES(sId),
           lastUpdated = VALUES(lastV)

但是...哪一列是UNIQUE(或PRIMARY)?IODKU 需要知道它何时是“重复”。

假设它是print。如果是这样,则print = VALUES(print)不需要。


推荐阅读