重复更新或使用CASE插入的MariaDB语法

时间:2019-10-29 20:04:04

标签: php syntax mariadb unique-constraint

我想对设备进行指纹识别,并将结果与​​Session 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';
        }

    }

加载文档后,将在客户端生成打印,并触发XHR到storePrint.php。希望更新一条记录,或者在该打印OR sessionId不存在的情况下,创建一条新记录。问题在于,print或sessionId都可以更改,而其他更改都没有。我需要找到一种方法(如果可能,使用单个查询)来检查是否存在打印或sessionId。如果存在,则更新其他记录(打印,如果我们找到具有相同sessionId或sessionId,lastVisited的记录,则为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 ...''),这时我返回了到第一个准备好的声明,然后来到这里进行指导... The table structure

Contents of the table

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

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

1 个答案:

答案 0 :(得分:0)

似乎您在努力工作。这不是您想要的吗?

animal = Animal.find_by(name:name, type:type) ? Animal.find_by(name:name, type:type) :  Animal.create(name:name, type:type);

但是... INSERT INTO prints (print,sessionId,lastUpdated) VALUES (:print,:sid,:lastC) ON DUPLICATE KEY UPDATE print = VALUES(print), sessionId = VALUES(sId), lastUpdated = VALUES(lastV) (或UNIQUE)是哪一列? IODKU需要知道何时是“重复”。

假设它是PRIMARY。如果是这样,则不需要print