我正在编写一些Java单元测试,我需要比较两个sql字符串,其中sql语句在语义上是等效的,但在语法上可能不同。我不能进行字符串比较,因为from子句和where子句的顺序可能不同但两个查询可能是等价的。
无论如何在java中执行此操作而不必编写自己的Oracle SQL Parser? :)
P.S。查询可能非常复杂!
谢谢!
答案 0 :(得分:3)
一般的答案是否定的,因为你总是可以调用隐藏图灵机的某种存储过程。 事实上,你可以在SQL语句中进行算术运算,我认为也会把你推到图灵悬崖上。
当然,理论家总是告诉我们一切都是不可能的,所以我们都应该翻身而死。
罗
那你能做什么?好吧,“简单”的可能性是规范化SQL查询,就像简化代数方程一样。如果你能以某种方式,对于一个SQL语句,将其“规范化”(转换)为完全相同的绝对最短的等效SQL,那么你可以规范化两个SQL语句并比较结果语句;如果它们是相等的模数标识符重命名,那么它们具有相同的“语义”。对于SQL中的每个运算符,它背后都有一些语义,以及一些等效运算,就像在代数中一样。因此,如果您可以为每个SQL运算符确定代数等价的集合,则可以使用最短的代数等价来替换每个代数计算,它们执行相同的操作。
为此,您必须能够解析SQL,并将SQL重写应用于已解析的SQL,这意味着您需要program transformation engine。 (你可以在Parsing and Rewriting Algebra)
看到这种模拟这并不适用于所有情况。首先,可能有几个相同长度的“最短”SQL语句是等效的( 2 + X 与 X + 2 相同但对aa来说并不明显工具)。现在你有一个定理证明问题(对于我们的X + 2例子,使用交换律来证明它们是相等的),回到理论上。其次,您可能不知道如何使用重写生成最短的序列;甚至数学方程式有时也必须在它们再次变小之前膨胀。从技术上讲,你必须搜索所有可能的代数等价来找到最短的,这是不可能的。
所以,在实践中也很难做到。所以,没有。
答案 1 :(得分:2)
不是您问题的直接解决方案,但您可能需要查看可能已涵盖您所需内容的JSqlParser。