我在Hypersonic DB(HSQLDB)中运行以下查询:
SELECT (CASE foo WHEN 'a' THEN 'bar' WHEN 'b' THEN 'biz' ....
ELSE 'fin' END ) FROM MyTable LIMIT 1
当“WHEN”子句的数量超过1000时,我在StackOverflowError
中得到了JDBC驱动程序抛出的Java org.hsqldb.jdbc.Util.sqlException()
。
这是非常奇怪的部分:我尝试将我的CASE
声明分解成碎片,例如: 100 WHEN条款后跟ELSE ( CASE foo WHEN ... ) END
。但即使进行了这次重写,我也完全采取相同的行为!
我没有在HSQLDB手册中看到任何对1000或其他任何限制的引用。救命啊!
答案 0 :(得分:1)
在CASE
声明中,您永远不应该接近1000个术语。在此之前很久,您应该将其他值放入单独的表中并通过加入来选择它们。
INSERT INTO MappingTable (foo, string) VALUES
('a', 'bar'), ('b', 'biz'), ...
SELECT COALESCE(m.string, 'fin')
FROM MyTable t LEFT OUTER JOIN MappingTable m USING (foo)
LIMIT 1;
Java API讲述StackOverflowError:
由于应用程序过于冗长而发生堆栈溢出时抛出。
所以我猜想当HSQLDB解析CASE
表达式时,每个WHEN
术语会向运行时堆栈添加另一个层(实际上每个WHEN
可能有几层)。
如果您的算术表达式具有1,000级嵌套括号,则可能会得到类似的StackOverflowError。
1,000的限制可能是可变的,具体取决于Java VM的实现,Java的版本,您运行的平台,可用的内存量等。它们可能不会在HSQLDB文档中记录它因为它是特定于平台的限制,而不是HSQLDB中内置的限制。
答案 1 :(得分:1)
完全消除CASE声明。
使用这1000个值创建一个表,然后只对该表进行内部联接。
答案 2 :(得分:1)
正如比尔所说,鉴于明显的HSQL解析器设计,删除的限制是不可能的。
在减轻限制方面(即通过将限制推到......超过1000的某个位置让自己达到1000个开关),你有两个选择。