在CASE WHEN语句中,如何在HSQLDB中获取1000多个项目?
-
22-07-2019 - |
题
我正在Hypersonic DB(HSQLDB)中运行以下查询: 通用标签
当“ WHEN”子句的数量超过大约1000时,我得到了JDBC驱动程序在StackOverflowError
中抛出的Java org.hsqldb.jdbc.Util.sqlException()
。
这真是一个很奇怪的部分:我试图用例如100 WHEN子句,后跟CASE
。但是即使进行了这样的重写,我也能得到完全相同的行为!
在HSQLDB手册中,我看不到任何限制为1000的引用。救命!
解决方案
在CASE
语句中,您永远都不应接近1000个术语。在此之前很久,您应该将其他值放在单独的表中,然后通过联接选择它们。
通用标签
Java API讲述了StackOverflowError:
由于应用程序递归太深而在堆栈溢出时抛出。
所以我想,当HSQLDB解析一个
CASE
表达式时,每个WHEN
术语都会在运行时堆栈中增加另一层(实际上每个WHEN
可能有几层)。如果您的算术表达式具有1,000个嵌套括号级别,则可能会遇到类似的StackOverflowError。
1,000的限制可能是可变的,具体取决于Java VM的实现,Java的版本,运行的平台,可用的内存量等。它们可能未在HSQLDB文档中进行记录。因为这是特定于平台的限制,而不是HSQLDB内置的限制。
其他提示
完全消除CASE语句。
使用这1000个值创建一个表,然后对该表进行内部联接。
如Bill所说,鉴于明显的HSQL解析器设计,不可能删除限制。
在减轻限制方面(即通过将限制提高到...超过1000来让自己进入1000个开关),您有两种选择。
- 在运行应用程序时增加VM中的堆栈大小。如果您使用的是Sun的Hotspot VM,则应该能够通过例如-XX:ThreadStackSize= 1024以每个线程使用1MB堆栈,而不是默认的512K。这样可以使您获得更大的递归深度。
- 您可以在由构造函数Thread(ThreadGroup,Runnable,String,long)创建的Thread中运行工作,其中最后一个参数是请求的堆栈大小。这可能行不通;如果您阅读了Javadoc,那是一个建议-非常欢迎VM忽略此请求。不确定Hotspot具体做什么,但这可能会有所帮助。
不隶属于 StackOverflow