我构建了一个查询,我想知道它是否适用于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的问题)。
答案 0 :(得分:6)
此确切语法仅适用于MySQL
。
这个构造是一个丑陋的解决方法:
UPDATE locks
SET value = 1
WHERE key = 'key1'
AND NOT EXISTS
(
SELECT NULL
FROM locks li
WHERE li.key IN ('key2', 'key3')
AND li.value > 0
)
适用于除MySQL
之外的所有系统,因为后者不允许UPDATE
或DELETE
语句中的目标表上的子查询。
答案 1 :(得分:3)
1)更新查询。
无法想象没有UPDATE
的RDBMS。 (?)
2)加入更新查询。
在PostgreSQL中,您将包含FROM from_list
的附加表。
3)非分组查询中的聚合函数。
PostgreSQL中不可能。使用子查询,CTE或Window函数。
但您的查询 已分组。 GROUP BY
子句没有拼写出来。这也适用于PostgreSQL。
即使存在,HAVING也会将查询转换为分组查询 没有GROUP BY子句。这和发生时的情况相同 查询包含聚合函数但不包含GROUP BY子句。
4)WHERE ... IN条件
适用于我所知道的任何RDBMS。
“附加条件”:假设在多线程环境中,此查询的副本永远不会与另一个副本交错。
PostgreSQL的multiversion model MVCC(多版本并发控制)在处理并发性方面优于MySQL。然而,在这方面,大多数RDBMS都优于MySQL。
处理查询时必须返回是否有任何值受到影响。
Postgres这样做,大多数RDBMS都这样做。
此外,此查询不会在PostgreSQL中运行,因为:
请参阅list of reserved words in Postgres and SQL standards 一个combined list for various RDBMS。
答案 2 :(得分:2)
这只能在mysql中使用,因为你使用的是“`”分隔符,它只是特定于mysql的。
如果用更“标准”的分隔符替换分隔符怎么办:那么它可能适用于所有现代DBMS(postgres,sql server,oracle),但我绝不会为所有人编写一般查询 - 我最好写一个每个使用过的(或可能使用的)DBMS的特定查询,以使用其特定的语言方言来获得最佳性能和查询可读性。
如果“作为辅助请求,我会很感激”标准SQL“上的任何资源。”“看看http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt