Ho una tabella cosi` composta:
CREATE DOMAIN text AS BLOB SUBTYPE 1;
CREATE TABLE tabella(id integer,
testo text);
Durante l'inserimento di un grosso campo di testo via Flamerobin (la
query salvata e` di oltre 200k), mi viene restituito il seguente
errore:
SQL Message : -104
Invalid token
Engine Code : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -104
Unexpected end of command - line 373, column 29
Ora, leggendo le limitazioni per Firebird riportate su Wikipedia, la
dimensione massima di un record e` di 64KiB mentre la dimensione massima
di un campo Blob e` di 2GiB, eppure non riesco ad eseguire l'insert.
Dove puo` essere il problema? Firebird? Flamerobin? Oppure sto
sbagliando approccio? L'insert la eseguo in questa maniera:
INSERT INTO tabella VALUES (1, '<grosso blocco di testo>');
Enrico
P.S. isql mi restituisce questo errore: Single isql command exceeded
maximum buffer size
P.P.S. la versione di Firebird che uso e` la 2.1, mentre Flamerobin e`
alla versione 0.9.2
P.P.P.S. se puo` essere utile, <grosso blocco di testo> e` un attachment
preso da una email e codificato in base64 (e` un file pdf)
> Ho una tabella cosi` composta:
>
> CREATE DOMAIN text AS BLOB SUBTYPE 1;
> CREATE TABLE tabella(id integer,
> testo text);
>
> Durante l'inserimento di un grosso campo di testo via Flamerobin (la
> query salvata e` di oltre 200k), mi viene restituito il seguente
> errore:
Hai gi� usato precedentemente campi blob?
Perch� io non sono riuscito a fare delle insert da SQL puro (uso la 1.5x
comunque).
Se fai INSERT TABELLA (id,testo) VALUES ('1','pluto'); funziona?
Utilizzo Adodb.Stream e posso allegare file di qualsiasi tipo e dimensione.
In alternativa *mi pare* che i varchar grossi li dichiari internamente come
BLOB o simile.
> Hai già usato precedentemente campi blob?
Non approfonditamente, ovvero ho sempre usato la sintassi che ho postato
> Perchè io non sono riuscito a fare delle insert da SQL puro (uso la 1.5x
> comunque).
Devo dire che la sintassi che ho postato ha un errore nella creazione
del domain. Il comando corretto e`:
CREATE DOMAIN text AS BLOB SUB_TYPE 1;
> Se fai INSERT TABELLA (id,testo) VALUES ('1','pluto'); funziona?
Si
> Utilizzo Adodb.Stream e posso allegare file di qualsiasi tipo e dimensione.
Personalmente uso Python e non ho mai avuto un problema del genere
> In alternativa *mi pare* che i varchar grossi li dichiari internamente come
> BLOB o simile.
Da quello che ho capito della documentazione, il SUB_TYPE 1 del BLOB
serve proprio per specificare che il campo conterra` del testo. A questo
punto, mi chiedo se il problema e` dovuto a dei limiti dei client che
utilizzo o ad un limite intrinseco di Firebird (e, personalmente, mi
preoccupo di quest'ultimo caso, in quanto mi costringerebbe ad usare dei
metodi specifici per eseguire degli insert in quel tipo di campo)
Enrico
> Devo dire che la sintassi che ho postato ha un errore nella creazione
> del domain. Il comando corretto e`:
>
> CREATE DOMAIN text AS BLOB SUB_TYPE 1;
Io ho una tabella con scritto nei metadati:
"CBLOB" BLOB SUB_TYPE 0 SEGMENT SIZE 80,
Da VB sono riuscito solo con ADODB.Stream, dopo un po' di prove.
Anche perch� io ci storo file word, excel, immagini ecc.
> Da quello che ho capito della documentazione, il SUB_TYPE 1 del BLOB
> serve proprio per specificare che il campo conterra` del testo. A questo
> punto, mi chiedo se il problema e` dovuto a dei limiti dei client che
> utilizzo o ad un limite intrinseco di Firebird (e, personalmente, mi
> preoccupo di quest'ultimo caso, in quanto mi costringerebbe ad usare dei
> metodi specifici per eseguire degli insert in quel tipo di campo)
La documentazione che ho a disposione non pare riportare niente.
In caso di TextBlob riporta una insert classica come la tua.
Hai provato a mettere una sequenza grande di carratteri della stessa
dimensione es. 'aaaaa ecc.'
Perch� magari c'� qualcosa all'interno del testo che stai salvando che gli
da noia.
Prova con una stringa sempre da 200KB ma di zeri o di lettere classiche.
Se ti da errore prova a calare la dimensione per capire se c'� un qualche
limite.
> Hai provato a mettere una sequenza grande di carratteri della stessa
> dimensione es. 'aaaaa ecc.'
Ho appena provato, ed ho due comportamenti differenti:
- Se eseguo la query su di una unica stringa[1], l'insert viene
eseguita.
- Se eseguo la query su piu` stringhe[2], l'insert va in
errore.
A questo punto mi chiedo se sia un problema del client o della libreria.
Domani vedro` di fare delle prove via Python (oramai sono curioso di
capire qual e` il motivo di questo comportamento)
Enrico
[1] INSERT INTO tabella VALUES(1, 'aaaaaaaaaaaaaaaaaaaa'); [3]
[2] INSERT INTO tabella VALUES(1, 'aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa'); [3]
[3] ovviamente ho replicato l'insert, ovvero in tutti e due casi si
trattava di 200k di testo
> Domani vedro` di fare delle prove via Python (oramai sono curioso di
> capire qual e` il motivo di questo comportamento)
Ok, direi che ho gia` un quadro piu` chiaro. Il codice Python
che ho utlizzato e` il seguente:
import kinterbasdb
con = kinterbasdb.connect(dsn='/home/enrico/tmp/db/test.fdb',
user='sysdba', password='masterkey')
cur = con.cursor()
f = open('/home/enrico/tmp/db/test.sql', 'r')
query = f.read()
cur.execute(query)
Il file test.sql contiene l'insert multilinea da 200k. All'esecuzione di
questo codice, mi viene riportato questo errore:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
kinterbasdb.ProgrammingError: (0L, 'SQL statement of 215160 bytes is
too long (max 65535 allowed). Consider using bound parameters to
shorten the SQL code, rather than passing large values as part of the
SQL string.')
In altre parole, KinterbasDB non riesce ad eseguire la query piu` grandi
di 64K. Provando quindi a modificare il codice in modo da passare il
valore , ottengo questo risultato:
f = open('/home/enrico/tmp/db/test.sql', 'r')
str_value = f.read()
cur.execute('INSERT INTO tabella VALUES(?, ?)', (1, str_value))
con.commit()
A questo punto posso confermare tre cose:
- I client SQL (o la libreria fbclient?) hanno un grosso limite
nell'inserimento di record strutturati in una determinata maniera
(limite che non saprei se puo` essere aggirato).
- Firebird riesce a gestire i campi BLOB di testo come uno si aspetta.
- Il pacchetto python-kinterbasdb (ovvero il driver Python per
Firebird) di Debian necessita veramente di un aggiornamento (ho
dovuto usare la versione 3.3 del driver compilandola a mano)
Grazie per il supporto, ad alcune considerazioni necessarie per capire
dov'era il problema non avevo veramente pensato
Enrico
> Grazie per il supporto, ad alcune considerazioni necessarie per capire
> dov'era il problema non avevo veramente pensato
Hai fatto tutto da solo ma ok :)