我已经在 Stackoverflow 上提出了我的问题,但还没有真正得到任何答案,所以我现在在这里尝试。
我有在下面的 PHP 脚本中运行的 MySQL 查询。
它的作用是插入一个新的项目任务记录,如果不存在具有该 ID 号的记录。
如果存在带有 ID 号的记录,则它会更新它应该更新的字段。
我遇到的问题是我需要它仅在date_modified
这些列之一的值更改时更新列... name
、、、、或description
status
type
priority
public function addOrUpdateTaskRecord($taskId, $projectId, $name, $description, $status, $priority, $type, $date_entered, $date_modified, $sort_order, $heading){
$sql = "
INSERT INTO
$this->tasksDbTableName(task_id, project_id, name, description, status, priority, type, date_entered, date_modified, sort_order, heading)
VALUES
('$taskId', '$projectId', '$name', '$description', '$status', '$priority', '$type', UTC_TIMESTAMP(), UTC_TIMESTAMP(), '$sort_order', '$heading')
ON DUPLICATE KEY UPDATE
name='$name',
description='$description',
status='$status',
priority='$priority',
type='$type',
date_modified=UTC_TIMESTAMP(),
sort_order='$sort_order',
heading='$heading'";
return $this->db->query($sql);
}
这里的另一位用户 Gordon Linoff 向我展示了我可能能够改变它date_modified=UTC_TIMESTAMP(),
并在适当的位置使用它......
date_modified = (case when name <> values(name) or
description <> values(description) or
status <> values(status) or
type <> values(type) or
priority <> values(priority)
then UTC_TIMESTAMP()
else date_modified
end)
这看起来很有希望,并且在 MySQL 中没有产生任何错误。它仍然在需要时插入新记录,并在它是现有记录时更新,但现在它总是更新该date_modified
字段,即使我的 CASE 语句中的其他字段没有更改。
我真的可以使用一些帮助来获得这样的高级功能或替代方法吗?
那里的数据库专家有什么帮助吗?
我的最新代码....
public function addOrUpdateTaskRecord($taskId, $projectId, $name, $description, $status, $priority, $type, $date_entered, $date_modified, $sort_order, $heading){
$sql = "
INSERT INTO
$this->tasksDbTableName(task_id, project_id, name, description, status, priority, type, date_entered, date_modified, sort_order, heading)
VALUES
('$taskId', '$projectId', '$name', '$description', '$status', '$priority', '$type', UTC_TIMESTAMP(), UTC_TIMESTAMP(), '$sort_order', '$heading')
ON DUPLICATE KEY UPDATE
name='$name',
description='$description',
status='$status',
priority='$priority',
type='$type',
date_modified = (case when name <> values(name) or
description <> values(description) or
status <> values(status) or
type <> values(type) or
priority <> values(priority)
then UTC_TIMESTAMP()
else date_modified
end),
sort_order='$sort_order',
heading='$heading'";
return $this->db->query($sql);
}
我的数据库表看起来像这样......
CREATE TABLE IF NOT EXISTS apoll_web_projects_tasks (
task_id bigint(20) NOT NULL default '0',
project_id varchar(70) NOT NULL default '0',
name varchar(255) NOT NULL,
description varchar(36) default NULL,
status varchar(20) DEFAULT NULL,
priority varchar(20) DEFAULT NULL,
type varchar(20) DEFAULT NULL,
date_entered datetime DEFAULT NULL,
date_modified datetime DEFAULT NULL,
sort_order int(12) DEFAULT NULL,
heading int(2) NOT NULL default '0',
PRIMARY KEY (task_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
以下是我的最终工作解决方案。原来,搬这...
到列表顶部,在这些字段上方...
所以最终的解决方案如下所示......
只需将 my
CASE Statement
移到其他设置字段上方的顶部,即可开始正常工作!似乎这些 DB 列字段
name
description
status
priority
type
在我的 Case 语句可以运行之前就已更新,这导致它们看起来总是与 DB 字段相同,并且从来没有任何不同,因此我的 Case 语句是无用的。将它移到顶部,它现在可以 100% 正确工作。希望有一天这会帮助遇到类似问题的人,因为 3 个站点上的许多人试图修复它但没有成功。只是将它移到顶部就可以了,所以在这种情况下,订单非常重要!] 感谢所有贡献时间尝试寻找解决方案的人,我始终感谢我在 StackExchange 网络站点上获得的帮助!
我建议拉出内联sql。然后,创建一个过程/触发器,您可以应用适当的
IF
块来捕获您要更新的绝对值。例如:这将 a.) 摆脱您的内联 sql b.) 允许数据检查完整性 c.) 以编程方式为您提供更清晰的 INSERT 语句。
反过来,这将允许您完成 INSERT / UPDATE 所需完成的逻辑;