Konsistente Methode der Textspalte Informix Datenbank einfügen mit JDBC und ODBC

StackOverflow https://stackoverflow.com/questions/483284

  •  20-08-2019
  •  | 
  •  

Frage

I Problem haben, wenn ich einige Daten zu Informix TEXT Spalte versuchen einfügen über JDBC. In ODBC kann ich einfach SQL wie folgt ausführen:

INSERT INTO test_table (text_column) VALUES ('insert')

aber in JDBC nicht funktionieren und ich bekam Fehler:

617: A blob data type must be supplied within this context.

ich für ein solches Problem gesucht und gefunden Nachrichten von 2003:

http://groups.google.com/group/comp.databases.informix/browse_thread/thread/4dab38472e521269?ie=UTF- 8 & oe = UTF-8 & q = Informix + Jdbc +% + 22A + BLOB-Daten + + Typ muss + + sein geliefert + innerhalb von + 22% dieser

Ich änderte meinen Code PreparedStatement zu verwenden. Jetzt funktioniert es mit JDBC, aber in ODBC, wenn ich versuche mit PreparedStatement Ich habe Fehler:

Error: [Informix][Informix ODBC Driver][Informix]
Illegal attempt to convert Text/Byte blob type.
[SQLCode: -608], [SQLState: S1000]

Testtabelle wurde erstellt mit:

CREATE TABLE _text_test (id serial PRIMARY KEY, txt TEXT)

Jython Code beiden Fahrer testen:

# for Jython 2.5 invoke with --verify
# beacuse of bug: http://bugs.jython.org/issue1127

import traceback
import sys
from com.ziclix.python.sql import zxJDBC

def test_text(driver, db_url, usr, passwd):
    arr = db_url.split(':', 2)
    dbname = arr[1]
    if dbname == 'odbc':
        dbname = db_url
    print "\n\n%s\n--------------" % (dbname)
    try:
        connection = zxJDBC.connect(db_url, usr, passwd, driver)
    except:
        ex = sys.exc_info()
        s = 'Exception: %s: %s\n%s' % (ex[0], ex[1], db_url)
        print s
        return
    Errors = []
    try:
        cursor = connection.cursor()
        cursor.execute("DELETE FROM _text_test")
        try:
            cursor.execute("INSERT INTO _text_test (txt) VALUES (?)", ['prepared', ])
            print "prepared insert ok"
        except:
            ex = sys.exc_info()
            s = 'Exception in prepared insert: %s: %s\n%s\n' % (ex[0], ex[1], traceback.format_exc())
            Errors.append(s)
        try:
            cursor.execute("INSERT INTO _text_test (txt) VALUES ('normal')")
            print "insert ok"
        except:
            ex = sys.exc_info()
            s = 'Exception in insert: %s: %s\n%s' % (ex[0], ex[1], traceback.format_exc())
            Errors.append(s)
        cursor.execute("SELECT id, txt FROM _text_test")
        print "\nData:"
        for row in cursor.fetchall():
            print '[%s]\t[%s]' % (row[0], row[1])
        if Errors:
            print "\nErrors:"
            print "\n".join(Errors)
    finally:
        cursor.close()
        connection.commit()
        connection.close()


#test_varchar(driver, db_url, usr, passwd)
test_text("sun.jdbc.odbc.JdbcOdbcDriver", 'jdbc:odbc:test_db', 'usr', 'passwd')
test_text("com.informix.jdbc.IfxDriver", 'jdbc:informix-sqli://169.0.1.225:9088/test_db:informixserver=ol_225;DB_LOCALE=pl_PL.CP1250;CLIENT_LOCALE=pl_PL.CP1250;charSet=CP1250', 'usr', 'passwd')

Gibt es eine Einstellung in JDBC oder ODBC eine Version des Codes haben für beide Fahrer?

Version Info:

  • Server: IBM Informix Dynamic Server Version 11.50.TC2DE
  • Client:
    • ODBC-Treiber 3.50.TC3DE
    • IBM Informix JDBC-Treiber für IBM Informix Dynamic Server 3.50.JC3DE
War es hilfreich?

Lösung

Zunächst einmal, sind Sie wirklich sicher, dass Sie eine Informix-TEXT-Typ verwendet werden soll? Der Typ ist ein Ärgernis teilweise zu nutzen, wegen der Probleme Sie konfrontiert sind. Es pre-dates alles in jedem SQL-Standard in Bezug auf große Objekte (TEXT ist noch nicht in SQL-2003 - obwohl etwa äquivalenten Strukturen, CLOB und BLOB sind). Und die Funktionalität von BYTE und TEXT Blobs wurde nicht geändert, da -. Oh, wir 1996 sagen, obwohl ich vermute, es ist ein Fall für die Wahl ein früheres Datum, wie 1991

Insbesondere, wie viele Daten planen Sie in den Textspalten speichern? Ihr Beispiel zeigt die Zeichenfolge ‚Insert‘; das heißt, nehme ich an, viel, viel kleiner, als man wirklich verwenden würde. Sie sollten sich bewusst sein, dass ein BYTE oder TEXT-Spalten verwendet einen 56-Byte-Descriptor in der Tabelle sowie eine separate Seite (oder Seiten), um die aktuellen Daten zu speichern. Also, für winzige Saiten so, es ist eine Verschwendung von Speicherplatz und Bandbreite (da die Daten für die BYTE oder TEXT-Objekte ausgeliefert werden zwischen Client und Server getrennt von dem Rest der Reihe). Wenn Ihre Größe nicht mehr als etwa 32 KB bekommt, dann sollten Sie bei Verwendung LVARCHAR suchen anstelle von Text. Wenn Sie Datengrößen über die Verwendung sein wird, dann BYTE oder TEXT oder BLOB oder CLOB sind vernünftige Alternativen, aber Sie sollten Räume bei der Konfiguration entweder blob aussehen (für BYTE oder TEXT) oder Smart-Klecks Plätze (BLOB oder CLOB). Sie können, und sind, TEXT IN DER TABELLE, anstatt in einem Blob Raum; beachten Sie, dass während mit einem Klecks Raum so Auswirkungen auf Ihre logischen Protokolle tun sie nicht alles beeinflussen, wie so viel.

Eine der Funktionen, die ich schon seit einem Jahrzehnt eine Kampagne oder so ist die Fähigkeit, Stringliterale in SQL-Anweisungen als Textliterale (oder BYTE Literale) zu übergeben. Das ist wegen der Erfahrung von Menschen wie Sie in Teil. Ich habe noch nicht gelungen, bekommen sie vor anderen Änderungen priorisiert, die vorgenommen werden müssen. Natürlich müssen Sie sich bewusst sein, dass die maximale Größe einer SQL-Anweisung ist 64 KB Text, so dass Sie zu groß eine SQL-Anweisung erstellen können, wenn Sie nicht vorsichtig sind; Platzhalter (Fragezeichen) in der SQL verhindert normalerweise, dass ein Problem zu sein -. und die Größe einer SQL-Anweisung zu erhöhen weiteres Merkmal Anforderung ist, die ich habe für geworben, aber etwas weniger inbrünstig

OK, unter der Annahme, dass Sie für die Verwendung von TEXT gute Gründe haben ... was als nächstes. Ich bin nicht klar, was Java (die JDBC-Treiber) hinter den Kulissen tut - abgesehen von zu viel - aber es ist eine faire Wette, dass es zu bemerken, dass eine Text ‚Locator‘ Struktur benötigt wird, und ist der Versand die Parameter in den richtigen Format. Es scheint, dass die ODBC-Treiber werden schwelgen Sie nicht mit ähnlichen Spielereien.

In ESQL / C, wo ich normal arbeiten, dann der Code mit BYTE und TEXT unterschiedlich von allem anderen zu behandeln (und BLOB und CLOB haben mit wieder anders behandelt werden). Aber Sie können eine Locator-Struktur erstellen und füllen (loc_t oder ifx_loc_t von locator.h - die nicht im ODBC-Verzeichnis sein kann, es ist in $ INFORMIXDIR / incl / esql Standardeinstellung) und übergeben, daß an den ESQL / C-Code als die Hostvariable für den entsprechenden Platzhalter in der SQL-Anweisung. Im Prinzip gibt es wahrscheinlich ein paralleles Verfahren für ODBC zur Verfügung. Sie können auf dem Informix-ODBC-Treiber manuell zu suchen, um es zu finden, though.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top