我正在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个开关),您有两种选择。

  1. 在运行应用程序时增加VM中的堆栈大小。如果您使用的是Sun的Hotspot VM,则应该能够通过例如-XX:ThreadStackSize= 1024以每个线程使用1MB堆栈,而不是默认的512K。这样可以使您获得更大的递归深度。
  2. 您可以在由构造函数Thread(ThreadGroup,Runnable,String,long)创建的Thread中运行工作,其中最后一个参数是请求的堆栈大小。这可能行不通;如果您阅读了Javadoc,那是一个建议-非常欢迎VM忽略此请求。不确定Hotspot具体做什么,但这可能会有所帮助。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top