我有两个疑问:自动检查两个SQL查询在语义上是相等
'UPDATE foo SET bar = baz WHERE a = b AND c = d'
和
'UPDATE foo SET bar = baz WHERE c = d AND a = b'
都是语义上相等(他们这样做),但一个简单的比较,将陈述他们不同,因为第一个有a = b AND c = d
,而第二个使用c = d AND a = b
。
如何检查两个查询在语义上是否相等?
这是一个明显简单的例子,可以通过在WHERE
节点处对语法树进行简单的字母排序来解决。我对通用的方法感兴趣,它也可以解决更复杂的查询 - 即使使用子查询。
进一步的限制是我没有访问数据库的权限,只能使用查询字符串。因此,运行查询是没有问题的,因为它不会反映查询的平等性。
为上面以粗体显示的文本的例子:
FooTable:
A | B | C
1 | xx | xx
2 | yy | zz
FooTable ':(FooTable' 是FooTable不同的数据库上)
A | B | C
1 | xx | xx
2 | ee | zz
3 | ss | xx
例为什么运行查询将不会产生有效结果:
1)在同一个数据库查询:
UPDATE FooTable SET B = 'rr' WHERE C = 'xx'
和
UPDATE FooTable SET B = 'rr' WHERE C = 'xx' OR B = 'ss'
两个查询将导致完全一样的,但平凡不等于。包括不同的数据库(相同的模式,但不同的数据)时
2)查询:
SELECT A,B,C FROM FooTable where C = 'xx'
AND
SELECT A,B,C FROM FooTable' where C = 'xx'
这些两个查询是平凡语义相等,但不会产生相同的结果。
运行它们,并比较结果集? – Stewart
在两者上运行解释计划,然后运行它们并比较结果? – sagi
@Stewart我无法访问运行查询的数据库。即使运行/比较和重置数据库之后的开销看起来像是一种有很多开销的方法。这因此不适用于大量的查询。 (Same @sagi) – Sim