descargar - jdbc java ejemplo
Método consistente de insertar una columna TEXT en la base de datos Informix usando JDBC y ODBC (1)
Tengo un problema cuando intento insertar algunos datos en la columna Informix TEXT a través de JDBC. En ODBC, simplemente puedo ejecutar SQL de esta manera:
INSERT INTO test_table (text_column) VALUES (''insert'')
pero esto no funciona en JDBC y obtuve un error:
617: A blob data type must be supplied within this context.
Busqué ese problema y encontré mensajes de 2003:
Cambié mi código para usar PreparedStatement. Ahora funciona con JDBC, pero en ODBC cuando intento usar PreparedStatement recibí un error:
Error: [Informix][Informix ODBC Driver][Informix]
Illegal attempt to convert Text/Byte blob type.
[SQLCode: -608], [SQLState: S1000]
La tabla de prueba fue creada con:
CREATE TABLE _text_test (id serial PRIMARY KEY, txt TEXT)
Código Jython para probar ambos controladores:
# 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'')
¿Hay alguna configuración en JDBC u ODBC para tener una versión de código para ambos controladores?
Información de la versión:
- Servidor: IBM Informix Dynamic Server versión 11.50.TC2DE
- Cliente:
- Controlador ODBC 3.50.TC3DE
- Controlador IBM Informix JDBC para IBM Informix Dynamic Server 3.50.JC3DE
En primer lugar, ¿de verdad está seguro de que quiere usar un tipo de Informix TEXT? El tipo es una molestia para usar, en parte debido a los problemas que enfrenta. Es anterior a cualquier cosa en cualquier estándar SQL con respecto a los objetos grandes (TEXT todavía no está en SQL-2003, aunque son estructuras aproximadamente equivalentes, CLOB y BLOB). Y la funcionalidad de los blobs BYTE y TEXT no ha cambiado desde, digamos, 1996, aunque sospecho que hay razones para elegir una fecha anterior, como 1991.
En particular, ¿cuántos datos está planeando almacenar en las columnas TEXT? Su ejemplo muestra la cadena ''insertar''; es decir, supongo, mucho más pequeño de lo que realmente usaría. Debe tener en cuenta que las columnas BYTE o TEXT utilizan un descriptor de 56 bytes en la tabla más una página separada (o un conjunto de páginas) para almacenar los datos reales. Por lo tanto, para cadenas pequeñas como esa, es una pérdida de espacio y ancho de banda (porque los datos para los objetos BYTE o TEXT se enviarán entre el cliente y el servidor por separado del resto de la fila). Si su tamaño no supera los 32 KB, debería utilizar LVARCHAR en lugar de TEXT. Si va a utilizar tamaños de datos superiores, entonces BYTE o TEXT o BLOB o CLOB son alternativas razonables, pero debe considerar la configuración de espacios de blobs (para BYTE o TEXT) o espacios de blobs inteligentes (para BLOB o CLOB). Puede, y está, usar TEXT IN TABLE, en lugar de en un espacio blob; tenga en cuenta que hacerlo afecta sus registros lógicos mientras que usar un espacio de blob no los afecta en absoluto.
Una de las características que he estado haciendo campaña durante aproximadamente una década es la capacidad de pasar literales de cadena en sentencias de SQL como literales de TEXTO (o literales de BYTE). Eso es en parte debido a la experiencia de personas como usted. Todavía no he tenido éxito en priorizarlo antes de que se realicen otros cambios. Por supuesto, debe tener en cuenta que el tamaño máximo de una instrucción SQL es 64 KB de texto, por lo que podría crear una declaración SQL demasiado grande si no tiene cuidado; los marcadores de posición (signos de interrogación) en el SQL normalmente evitan que sea un problema, y aumentar el tamaño de una declaración SQL es otra solicitud de función que he estado haciendo campaña, pero con un poco menos de ardor.
De acuerdo, suponiendo que tienes razones sensatas para usar TEXT ... ¿qué sigue? No estoy seguro de lo que Java (el controlador JDBC) está haciendo detrás de las escenas, aparte de demasiado, pero es una apuesta justa que se da cuenta de que se necesita una estructura de ''localizador'' de TEXTO y está enviando el parámetro en la dirección correcta formato. Parece que el controlador ODBC no te está complaciendo con engaños similares.
En ESQL / C, donde normalmente trabajo, el código tiene que tratar con BYTE y TEXT de forma diferente a todo lo demás (y BLOB y CLOB tienen que tratarse de manera diferente de nuevo). Pero puede crear y completar una estructura de localizador (loc_t o ifx_loc_t desde locator.h, que puede no estar en el directorio ODBC, está en $ INFORMIXDIR / incl / esql por defecto) y pasarlo al código ESQL / C como el variable de host para el marcador de posición relevante en la declaración de SQL. En principio, probablemente haya un método paralelo disponible para ODBC. Sin embargo, es posible que tenga que consultar el manual del controlador ODBC de Informix para encontrarlo.