Frage

Ich betreibe die folgende Abfrage in Hyperschall -DB (HSQLDB):

SELECT (CASE foo WHEN 'a' THEN 'bar' WHEN 'b' THEN 'biz' ....
        ELSE 'fin' END ) FROM MyTable LIMIT 1

Wenn die Anzahl der "When" -Klauseln ungefähr 1000 überschreiten, bekomme ich eine Java StackOverflowError vom JDBC -Treiber geworfen in org.hsqldb.jdbc.Util.sqlException().

Hier ist der wirklich seltsame Teil: Ich habe versucht, meine zu trennen CASE Aussage in Stücke mit zB 100, wenn Klauseln gefolgt von ELSE ( CASE foo WHEN ... ) END. Aber selbst mit diesem Umschreiben bekomme ich exakt Das gleiche Verhalten!

Ich sehe keinen Hinweis auf eine Grenze von 1000 oder etwas anderes im HSQLDB -Handbuch. Hilfe!

War es hilfreich?

Lösung

Sie sollten niemals in einem fast 1000 Amtszeit in a kommen CASE Aussage. Lange zuvor sollten Sie die anderen Werte in eine separate Tabelle einfügen und sie durch Beitritt auswählen.

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 sagt über Stackoverflowerror:

Wenn ein Stapelüberlauf auftritt, tritt eine Anwendung zu tief auf.

Also würde ich das vermuten, wenn Hsqldb a CASE Ausdruck, jeweils WHEN Der Term fügt dem Laufzeitstapel eine weitere Ebene hinzu (wahrscheinlich wahrscheinlich mehrere Ebenen pro Schicht WHEN).

Sie würden wahrscheinlich einen ähnlichen Stackoverflowerror bekommen, wenn Sie einen arithmetischen Ausdruck mit 1.000 Ebenen verschachtelter Klammern hätten.

Die Grenze von 1.000 ist wahrscheinlich variabel, abhängig von der Implementierung der Java VM, der Version von Java, der Plattform, auf der Sie ausführen Plattformspezifische Grenze, nicht in HSQLDB eingebaut.

Andere Tipps

Beseitigen Sie die Fallerklärung vollständig.

Machen Sie eine Tabelle mit diesen 1000 Werten und machen Sie dann einfach eine innere Verbindung zu dieser Tabelle.

Wie Bill sagte, ist es unmöglich zu Löschen Die Grenze angesichts des scheinbaren HSQL -Parser -Designs.

In Bezug auf die Linderung des Grenzwerts (dh sich zu 1000 Switches zu erhalten, indem Sie nur das Limit auf ... irgendwo über 1000) haben, haben Sie zwei Optionen.

  1. Erhöhen Sie die Stapelgröße in der VM, wenn Sie Ihre App ausführen. Wenn Sie Sun's Hotspot VM verwenden, sollten Sie in der Lage sein, EG -xx zu übergeben: ThreadStacksize = 1024, um einen 1 -MB -Stapel pro Thread anstelle des Standards 512K zu verwenden. Dadurch können Sie eine größere Rekursionstiefe erreichen.
  2. Sie können Ihre Arbeiten in einem Thread ausführen, der vom Konstruktor -Thread (Threadgroup, Runnable, String, Long) erstellt wurde, wobei der letzte Parameter eine angeforderte Stapelgröße ist. Dies kann funktionieren oder nicht; Wenn Sie den Javadoc lesen, ist dies ein Vorschlag - VMs können diese Anfrage ignorieren. Ich bin mir nicht sicher, was Hotspot speziell tut, aber es könnte helfen.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top