我想对设备进行指纹识别,并将结果与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 ...''),这时我返回了到第一个准备好的声明,然后来到这里进行指导...
因此,最后,我要重写查询,重新设计表还是两者兼而有之??
更新:
我遇到的实际问题是在sessionId列上违反了完整性约束。我最终遇到了冲突,其中打印匹配WHERE id=1
并且sessionId匹配WHERE id=14
MySQL决定它将更新id=1
并由于重复的sessionId而导致完整性约束。 如何使用CASE
来DELETE
其他匹配的记录行?
答案 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
。