Newsgroup: it.comp.software.database
Titolo: Firebird e limiti

Ho come l'impressione di essermi incocciato in un limite di Firebird...
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)

 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.

 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

 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.

 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

 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

 dov'era il problema non avevo veramente pensato
Hai fatto tutto da solo ma ok :)