php - 重复更新时插入或使用 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
匹配的记录行?
解决方案
看来你工作太辛苦了。这不是你想要的吗?
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)
不需要。
推荐阅读
- list - Dart:实现 fromJson 函数的泛型类列表
- sql - 如何更新 SQL 表以去除 9 个字符串中的左侧 3 个字符?
- c# - Winforms - 丢弃不需要的双击
- windows - 在权限被拒绝的情况下使用 BASH 脚本出错,但是当直接在 bash shell 中运行命令时,它会被执行
- javascript - Discord.js 如何获取已获取频道的“消息”属性?
- c - 如何在 C 中获取 UWP 应用程序的安装位置?
- javascript - 字体真棒图标不会在工具提示之前附加
- php - 扩展构造函数而不指定参数
- typescript - 带有空警告的打字稿编译
- react-native - 是否可以将 PanResponder 添加到 Stack.Navigator?