método consistente de inserção de coluna de texto a base de dados utilizando Informix JDBC e ODBC

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

  •  20-08-2019
  •  | 
  •  

Pergunta

Eu tenho problema quando eu tento inserir alguns dados para Informix coluna TEXT via JDBC. Em ODBC posso simplesmente executar SQL como esta:

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

mas isso não funcionam em JDBC e eu tenho de erro:

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

Eu procurei por esse problema e encontrou mensagens a partir de 2003:

http://groups.google.com/group/comp.databases.informix/browse_thread/thread/4dab38472e521269?ie=UTF- 8 & OE = UTF-8 & q = + Informix JDBC +% 22A + + gota de dados + + tipo deve ser + + + fornecido dentro de + 22% deste

Eu mudei meu código para usar PreparedStatement. Agora ele trabalha com JDBC, mas em ODBC quando tento usar PreparedStatement I obteve o erro:

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

tabela de teste foi criado com:

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

código Jython para testar ambos os pilotos:

# 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')

Existe alguma configuração no JDBC ou ODBC para ter uma versão do código para ambos os pilotos?

info Versão:

  • Servidor: IBM Informix Dynamic Server Versão 11.50.TC2DE
  • Cliente:
    • driver ODBC 3.50.TC3DE
    • IBM Informix JDBC Driver para IBM Informix servidor 3.50.JC3DE dinâmico
Foi útil?

Solução

Primeiro, você tem certeza que deseja usar um tipo TEXT Informix? O tipo é um incômodo de usar, em parte por causa dos problemas que estão enfrentando. Ele antecede a qualquer coisa em qualquer padrão SQL em relação às grandes objetos (texto ainda não está na SQL-2003 - embora estruturas aproximadamente equivalentes, CLOB e BLOB, são). E a funcionalidade do BYTE e TEXT blobs não foi alterado desde então -. Oh, digamos 1996, embora eu suspeito que há um caso para a escolha de uma data anterior, como 1991

Em particular, a quantidade de dados que você está planejando para armazenar as colunas de texto? Seu exemplo mostra a string 'inserção'; isto é, presumo, muito, muito menor do que você poderia realmente usar. Você deve estar ciente de que um byte ou colunas de texto utiliza um descritor de 56 bytes na tabela, mais uma página separada (ou conjunto de páginas) para armazenar os dados reais. Então, para cordas pequenas como essa, é um desperdício de espaço e largura de banda (porque os dados para o byte ou TEXT objetos serão enviados entre o cliente eo servidor separadamente do resto da linha). Se o tamanho não vai ficar acima de cerca de 32 KB, então você deve olhar usando LVARCHAR em vez de texto. Se você vai usar tamanhos de dados acima que, em seguida, BYTE ou TEXT ou BLOB ou CLOB são alternativas sensatas, mas você deve olhar para a configuração de ambos os espaços blob (para BYTE ou TEXT) ou espaços blob inteligentes (para BLOB ou CLOB). Você pode, e são, usando o texto na tabela, em vez de em um espaço blob; estar ciente de que isso afeta seus logs lógicos, enquanto utilizando um espaço blob não tem impacto sobre eles qualquer coisa como tanto.

Uma das características que eu fui fazer campanha por uma década ou assim é a capacidade de passar strings literais em instruções SQL como literais de texto (ou literais byte). Isso é, em parte por causa da experiência de pessoas como você. Eu ainda não foram bem sucedidos em fazê-la prioridade à frente de outras mudanças que precisam ser feitas. Claro, você precisa estar ciente de que o tamanho máximo de uma instrução SQL é 64 KB de texto, para que você possa criar muito grande uma instrução SQL se você não for cuidadoso; espaços reservados (pontos de interrogação) no SQL normalmente impedir que sendo um problema - e aumentar o tamanho de uma instrução SQL é um outro pedido de recurso que eu tenho feito campanha para, mas um pouco menos ardentemente

.

OK, supondo que você tem boas razões para usar texto ... o que vem depois. Eu não estou claro o que Java (o driver JDBC) está fazendo nos bastidores - para além de muito - mas é uma aposta justa que ele está percebendo que a estrutura do texto 'localizador' é necessário e é o transporte o parâmetro na correta formato. Parece que o driver ODBC não está entregando-lhe peripécias semelhantes.

Em ESQL / C, onde eu normalmente trabalho, então o código tem de lidar com BYTE e um texto diferente de tudo o resto (e BLOB e CLOB tem que ser tratada de forma diferente novamente). Mas você pode criar e preencher uma estrutura localizador (loc_t ou ifx_loc_t de locator.h - o que pode não estar no diretório ODBC, está em $ INFORMIXDIR / incl / esql por padrão) e passar isso para o código ESQL / C como o variável do host para o espaço reservado relevante na instrução SQL. Em princípio, não é provavelmente um método paralelo disponível para ODBC. Você pode ter que olhar para o manual do driver ODBC Informix para encontrá-lo, no entanto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top