+ Rispondi al messaggio
Visualizzazione dei risultati da 1 a 8 su 8

Scrivere ed inviare a stored oracle parametro clob

  1. #1
    L'avatar di maximum
    maximum non è in linea Scolaretto
    Post
    468
    Like Inviati  
    0
    Like Ricevuti  
    0
    Ciao a tutti,
    vi scrivo circa un problema relativo all'oggettodi sopra.

    Praticamente io ho un'interfaccia da cui posso selezionare eventuali allegati. Al submit della pagina, devo effettuare la scrittura di tale file e dopo averlo composto, inviarlo come clob alla stored procedure oracle che ne richiede il parametro.

    Anticipo che l'applicazione web in questione fa uso di Struts 2.0.

    Riporto inoltre alcuni passaggi che effettuo per effettuare l'operazione che però nonostante tutto mi restituisce il seguente errore:

    java.sql.SQLException: La dimensione dei dati è superiore alla dimensione massima per questo tipo: 33280

    1)Sulla mia action faccio:

    //inizio upload
    InviaMailForm inviaMailForm = (InviaMailForm)form;
    					
    FormFile file = inviaMailForm .getFile();	
    
    if (file.getFileSize() > 0)
        numAllegati = 1;
    //fine upload
    
    2) Sulla mia classe DAO faccio:

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
    if (numAllegati == 1) {
        lunghAllegato = file.getFileSize();
        InputStream is = file.getInputStream();
    						     	
        // Viene ricomposto l'InputStream
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) > -1) {
                  baos.write(buffer, 0, len);
        }
    							    
        sqlStmt = "call NOTIFICA_MAIL.INSERT_MAIL_ATTACH(" + idMailNotify + ", '" +file.getFileName() + "', ?, 3, ?, ?)";
        cstmt = conn.prepareCall("{" + sqlStmt + "}");
        InputStream is1 = new ByteArrayInputStream(baos.toByteArray()); 
        cstmt.setBinaryStream(1, is1, lunghAllegato);
        cstmt.setInt(2, id_error);										  
        cstmt.setString(3, ws_mail_error);
        cstmt.execute();
    
        baos.flush();		
    }
    
    L'errore lo prendo alla riga in grassetto, precisamente
    cstmt.setBinaryStream(1, is1, lunghAllegato);
    
    Come risolvo? Cosa sbaglio?

    Grazie anticipatamente.

  2. #2
    L'avatar di bottomap
    bottomap non è in linea Moderatore Globale
    Post
    4,130
    Like Inviati  
    0
    Like Ricevuti  
    0
    Ciao,

    E' sempre bene essere estremamente attenti con i blob... nove volte su dieci il problema riguarda la lunghezza passata come terzo parametro alla setBinaryStream.

    Attenzione in particolar modo a:
    - un buffer vuoto (in quel caso devi usare qualcosa del tipo cstmt.setNull(n, java.sql.Types.BLOB) // o CLOB o il tipo che ti serve
    - la dimensione del buffer. Se non è esattamente quella che indichi alla setBinaryStream otterrai un errore.

    In particolar modo il secondo caso dovrebbe essere quello che ti da problemi. Ottieni la lunghezza dalla getFileSize, ma poi allochi un buffer di 1024. La lunghezza di quello che stai cercando di mandare al blob è 1024 e non è detto che sia la lunghezza del file originale.
    La cosa migliore da fare, per evitare di inviare pochi byte seguiti da un bel po'di zeri (o peggio solo una porzione del file) sarebbe di allocare buffer non su 1024 ma su lunghAllegato (il ché tra l'altro ti permette anche di gestire file più grandi di 1k).

    Ciaociao
    ℹ️ Leggi di più su bottomap ...

  3. #3
    L'avatar di maximum
    maximum non è in linea Scolaretto
    Post
    468
    Like Inviati  
    0
    Like Ricevuti  
    0
    Ciao,
    ho provato a fare quanto mi hai suggerito, cambiato questa riga da:

    byte[] buffer = new byte[1024];
    
    a
    byte[] buffer = new byte[lunghAllegato];
    
    Ma l'errore continua ad essere lo stesso che ho riportato nel commento di apertura.

  4. #4
    L'avatar di bottomap
    bottomap non è in linea Moderatore Globale
    Post
    4,130
    Like Inviati  
    0
    Like Ricevuti  
    0
    Ciao,

    Non ho letto il primo post attentamente.
    Fatte salve le altre indicazioni (usa sempre la dimensione effettiva del buffer per la setBinaryStream - anzi meglio che se passi un byte[] b usi sempre b.lenght per la dimensione - così sei certo che il problema non sia quello), come hai dichiarato il campo in oracle?
    Un CLOB normalmente dovrebbe poter contenere fino a 2GB di dati... ma da l'errore che ottieni sembra che la dimensione massima impostata non sia quella.
    ℹ️ Leggi di più su bottomap ...

  5. #5
    L'avatar di maximum
    maximum non è in linea Scolaretto
    Post
    468
    Like Inviati  
    0
    Like Ricevuti  
    0
    Il campo della stored è dichiarato così:
    attach_file      IN blob
    

  6. #6
    L'avatar di bottomap
    bottomap non è in linea Moderatore Globale
    Post
    4,130
    Like Inviati  
    0
    Like Ricevuti  
    0
    Ok... sembrea ci sia un limite di 32k per i blob in input alle stored procedures:

    Working with LOBs and BFILEs

    Evitare il problema sembra non sia possibile direttamente (a parte evitare di mandare più di 32k o comprimere preventivamente il dato).
    Spesso viene usato l'accorgimento di creare il blob vuoto e poi fare un update manuale, il tutto in una singola transazione... non so se è applicabile nel tuo caso.
    In alternativa, se fattibile, potresti buttare la stored procedure ed effettuare la insert o update direttamente da codice (in quel caso il limite non dovrebbe esserci).
    ℹ️ Leggi di più su bottomap ...

  7. #7
    L'avatar di maximum
    maximum non è in linea Scolaretto
    Post
    468
    Like Inviati  
    0
    Like Ricevuti  
    0
    Per ragioni di lavoro, non posso prescindere dalla stored oracle di cui fatta menzione.

    Per cui devo procedere tramite questa.

  8. #8
    L'avatar di bottomap
    bottomap non è in linea Moderatore Globale
    Post
    4,130
    Like Inviati  
    0
    Like Ricevuti  
    0
    Allora l'unica è non impostare il blob e fare un update del blob dopo l'esecuzione della stored procedure (ammesso sia un'operazione che puoi fare), oppure assicurarsi di mandare contenuto sempre <32k... non ci sono tante alternative...

    Il limite per un parametro blob passato ad una stored proc è 32k.
    ℹ️ Leggi di più su bottomap ...

+ Rispondi al messaggio

Potrebbero interessarti anche ...

  1. Inviare parametro a Report
    Da arti86 nel forum Microsoft Access
    Risposte: 21
    Ultimo Post: 08-03-2011, 22:44
  2. Risposte: 0
    Ultimo Post: 09-07-2010, 10:10
  3. recupero dati da stored procedure oracle
    Da bariloche nel forum Visual Basic 6
    Risposte: 1
    Ultimo Post: 05-10-2009, 11:25
  4. [ASP.Net]Stored precedure - inviare dati
    Da perla0279 nel forum ASP 3, ASP .Net
    Risposte: 7
    Ultimo Post: 07-02-2008, 22:35
  5. [VB.NET] Inviare un parametro al Report..
    Da web_race nel forum Visual Basic 6
    Risposte: 4
    Ultimo Post: 13-02-2004, 11:36