我已经构建了一个查询,我想知道它是否适用于除 MySQL 之外的任何数据库。我从未真正使用过其他数据库,所以我对这些差异不太了解。
UPDATE `locks` AS `l1`
CROSS JOIN (SELECT SUM(`value`) AS `sum` FROM `locks`
WHERE `key` IN ("key3","key2")) AS `l2`
SET `l1`.`value` = `l1`.`value` + 1
WHERE `l1`.`key` = "key1" AND (`l2`.`sum` < 1);
以下是我所依赖的特定功能(我能想到的):
我相信人们会很好奇这到底是做什么的,这可能还包括可能不普遍的数据库功能。这是使用数据库的互斥实现,旨在用于 Web 应用程序。在我的情况下,我需要它是因为某些用户操作会导致表被删除并使用不同的列重新创建,如果应用程序的其他部分尝试插入数据,我想避免错误。因此,该实现专门用于解决 the readers-writers problem 。
此查询假设存在一个包含两个字段的
locks
表:key
(varchar) 和 value
(int)。它还假设该表包含一行使得 key
="key1"。然后它尝试为“key1”增加 value
。只有当列表 key
中的每个 ("key2","key3")
关联的 value
为 0 时才会这样做(l2
的 WHERE 条件是假设 value
永远不会为负的近似值)。因此,如果满足某些条件,则此查询仅“获得锁”,大概是原子方式。然后,应用程序通过查询的返回值检查它是否收到锁定,该值可能说明有多少行受到影响。当且仅当没有行受到影响时,应用程序才不会收到锁。因此,以下是从查询本身无法辨别的附加条件:
作为次要请求,我将不胜感激任何有关“标准 SQL”的资源。我听说过它,但从未找到任何类型的定义,当 MySQL 文档说“此功能是标准 SQL 的扩展”时,我觉得我遗漏了很多东西。
根据响应,此查询应该在所有系统中都能更好地工作:
UPDATE locks AS l1
CROSS JOIN (SELECT SUM(val) AS others FROM locks
WHERE keyname IN ('key3','key2')) AS l2
SET l1.val = l1.val + 1
WHERE l1.keyname = 'key1' AND (l2.others < 1);
因为好的答案,为大家点赞。标记的答案旨在直接回答我的问题,即使只是针对另一个 DBMS,即使可能有更好的解决方案来解决我的特定问题(甚至一般的跨平台 SQL 问题)。
最佳答案
对于 PostgreSQL
无法想象没有 UPDATE
的 RDBMS。 (?)
在 PostgreSQL 中,您将使用 FROM from_list
包含其他表。
在 PostgreSQL 中不可能。为此使用子查询、CTE 或窗口函数。
但是您的查询 是 分组的。 GROUP BY
子句只是没有详细说明。这也适用于 PostgreSQL。
(Quote from the manual)。
适用于我所知道的任何 RDBMS。
PostgreSQL 的 multiversion model MVCC (Multiversion Concurrency Control) 在处理并发方面优于 MySQL。再说一次,大多数 RDBMS 在这方面都优于 MySQL。
Postgres 这样做,大多数 RDBMS 都这样做。
此外,此查询不会在 PostgreSQL 中运行,因为:
请参阅 list of reserved words in Postgres and SQL standards 。
一个 combined list for various RDBMS 。
关于mysql - 哪些数据库可以运行以下 SQL?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7856413/