2016-07-15 16 views
0

Ich brauche eine einfache Abfrage mit Oracle, Java und Mybatis schreiben:In-Memory-Datenbank unterstützt proprietäre INSERT alle Oracle-Syntax

select * from FOO foo where foo.id IN (ids) 

Nun ist ids eine große Sammlung von Zeichenketten, etwa 7000. Leider Orakel hat 1000 Elemente Grenze für IN-Klausel.

Um dies zu überwinden, kann ich entweder:

  1. verketten die Abfrage dynamisch, so wird es: Ich bin nicht sicher, ob es überhaupt funktioniert und ich bezweifle es wirklich gut
  2. Verwendung vorübergehend führt Tabelle und schreiben Sie die Abfrage um: select * from FOO foo join SOME_TEMPORARY_ID tempids on foo.id = tempids.id.

Ich habe mich entschieden, für 2 Option zu gehen. Bevor ich die Abfrage ausführe, muss ich irgendwie eine effiziente Batch-Einfügung zu Oracle durchführen. Leider hat Oracle proprietäre Syntax Batch-Einsätze zu tun:

INSERT ALL 
INTO some_table VALUES ('foo') 
INTO some_table VALUES ('foo1') 
INTO some_table VALUES ('foo2') 
.... 
INTO some_table VALUES ('foo12345') 
SELECT * FROM DUAL 

Nun, ich habe nicht erwähnt, aber ich möchte einen Integrationstest für das schreiben, idealerweise H2 verwenden oder andere inmemory Datenbank. Natürlich unterstützt H2 diese Syntax nicht. Weder macht HSQLDB.

Kennen Sie eine In-Memory-Datenbank, die proprietäre Oracle-Syntax vollständig unterstützt? Oder zumindest diese spezielle INSERT ALL-Klausel?

Antwort

2

Danke, dass Sie Ihr Hauptproblem beschreiben. Check, kann dies dazu beitragen können Sie

where (foo.id, 0) in (('1', 0), ('2', 0),...) 

Diese einfache Abhilfe nicht als Einschränkung hat. Wenn diese Antwort nicht angebracht wäre, lassen Sie es mich wissen. Ich lösche diese Antwort und denke noch einmal an dein Kindproblem.

+0

Was ist mit der Leistung? Was sollte leistungsfähiger sein - mit temporären Tabellen oder 7k Elemente IN-Klausel? – slnowak

+0

@slnowak Sie bemerken, dass IDs Sammlung ist, warum einfach smt wie diese 'wählen * aus FOO foo where foo.id IN (* aus Tabelle (Sammlung IDs))'. Wo IDs ist geschachtelte Tabelle. Sie können IDs darin ziehen und dann Abfrage ausführen. Über Performance Ich denke, geschachtelte Tabelle ist die beste, temporary die zweite und in-Condition die dritte. –

+0

Können Sie die Syntax und das Feature selbst ein wenig mehr erklären? Ich wusste nicht, dass es existiert. Entspricht es mehr oder weniger dem Erstellen einer temporären Tabelle? Und leidet es nicht unter diesem 1k IN-Klausellimit? – slnowak

0

Die Grenze der Länge einer einzelnen INSERT Anweisung (das heißt die Anzahl der Datensätze, die Sie Wert für angeben) ist ein Hinweis darauf, dass dieser Vorganginsert Aussagen am besten ist wirklich ausgeführt mit mehr.

Können Sie über eine Liste von id Werten in einem Programm iterieren, indem Sie eine (oder mehrere) gleichzeitig in Ihre temporäre Tabelle einfügen, die Sie dann für Ihre letzte Abfrage verwenden können?

Natürlich ähnelt dies schließlich Ihrer ursprünglichen Option # 1, aber es ist wirklich eine Kombination aus # 1 und # 2, denke ich. Wie auch immer, es wird funktionieren! :)

+0

Es geht nicht um die Begrenzung der INSERT-Anweisung, sondern um die Begrenzung der IN-Klausel. – slnowak

+1

Ich schlage vor, die Klausel 'IN' nicht verwenden zu müssen, indem ich mich der Tabelle 'temp' anschließe, die alle IDs enthält. Wie das OP erklärt, besteht die Herausforderung darin, die IDs in die temporäre Tabelle einzufügen, was meine Antwort hilft. Sie würden immer noch der "Liste der IDs" beitreten, aber mit einem 'JOIN' anstelle von' IN'. – SlimsGhost

1

Ok, also ich habe entschieden, dass, wenn ich wirklich Oracle proprietäre Features/Syntax verwenden will/muss, dann testen wir es gegen Live-Orakel.

Also, wenn Sie nicht über die Ausführungszeit ist es egal und passieren den Zugang zu haben Docker tun auf dem CI-Server, dann empfehle ich Ihnen diese ausgezeichneten Bibliotheken: https://mvnrepository.com/artifact/org.testcontainers (https://github.com/testcontainers/testcontainers-java), einschließlich Oracle-xe-Modul.

Ich war in der Lage, Orakel-Xe-Container während meiner Integration Tests zu spinnen und gegen Live-Oracle-Instanz zu testen.