我有兩個疑問:自動檢查兩個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