2010-06-22 21 views
0

Je souhaite renvoyer certaines données en tant que Blob à partir d'une procédure stockée DB2 écrite en Java.Création dynamique de Blob dans une procédure mémorisée DB2 Java

C'est le code pour générer la procédure sur le serveur DB2:

CREATE PROCEDURE CLUB.P_CLUB_GET_BACKUP (IN CLUBID INTEGER, 
              IN BNR INTEGER, 
              OUT BACKUP BLOB(50000000)) 
NO SQL 
NOT DETERMINISTIC 
LANGUAGE Java 
EXTERNAL NAME 'P_CLUB_GET_BACKUP:ch.swissasp.vvv.procedures.P_GET_BACKUP1.p_GET_BACKUP1' 
FENCED 
THREADSAFE 
PARAMETER STYLE JAVA 

Et le code Java correspondant est le suivant:

/** 
* SQLJ Stored Procedure P_GET_BACKUP 
* @param clubID 
* @param backupID 
* @param Backup 
*/ 
package ch.swissasp.vvv.procedures; 

import java.io.File; 
import java.io.FileInputStream; 
import java.sql.SQLException; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipOutputStream; 

    public class P_GET_BACKUP1 
    { 
    public static void p_GET_BACKUP1(int clubID, int backupNr, java.sql.Blob[] backup) 
     throws SQLException, 
     Exception 
    { 
     // create blob and return as output parameter 'backup' 
    } 
    } 

Ce que je aurais besoin est maintenant un moyen de générer un Blob à partir de certaines données binaires générées dans la procédure stockée (donc le blob ne provient pas d'une requête mais lit les données qui résident sur le serveur de base de données) et renvoie ensuite ce blob comme paramètre de sortie 'backup'. Le problème est, que je n'ai aucune idée de comment créer dynamiquement un blob, comme java.sql.Blob lui-même est une interface. Je peux créer un blob en utilisant un SQL factice en tant que tel:

// create a blob the complicated way... 
Connection con = DriverManager.getConnection("jdbc:default:connection"); 
con.setReadOnly(true); 
PreparedStatement stmt = con.prepareStatement("VALUES (Cast(? AS Blob))"); 
stmt.setBytes(1, new byte[0]); 
ResultSet rs = stmt.executeQuery(); 
rs.next(); 
Blob blob = rs.getBlob(1); 
rs.close(); 

Et puis utiliser comme ceci:

OutputStream out = blob.setBinaryStream(1L); // get output stream to blob 
// code to write the data to output stream 
out.close(); // close blob 
backup[0] = blob; // set output param 

Mais je préférence être en mesure de remplacer tout ce code SQL avec quelque chose comme ceci:

java.sql.Blob blob = new DB2Blob(); // dynamically allocate blob 

Toutes les idées s'il existe cette possibilité de créer dynamiquement un blob dans DB2?

+0

Très en retard à cette partie, mais ne pourriez-vous pas créer un SerialBlob et le renvoyer? Il implémente l'interface blob et possède un constructeur byte []. http://docs.oracle.com/javase/7/docs/api/javax/sql/rowset/serial/SerialBlob.html – Mike

+0

Cela semble prometteur. Va tester si j'ai un peu de temps. –

Répondre

0

Voici ce que suggère IBM. Plutôt que d'utiliser une procédure stockée DB2, vous pouvez simplement faire la requête à partir de votre code Java.

PreparedStatement preparedStatement = 
    connection.prepareStatement(
    "SELECT BOOKCOVER FROM BOOKCOVERS WHERE BOOKISBN=?"); 
preparedStatement.setString(1, "0738425826"); 
ResultSet resultSet = preparedStatement.executeQuery(); 
while (resultSet.next()) { 
    // materialization of the Blob 
    Blob blob = resultSet.getBlob(1); 
    InputStream inputStream = blob.getBinaryStream(); 
    File fileOutput = new 
     File("C:\\clonedredbookcover.jpg"); 
    FileOutputStream fo = new 
     FileOutputStream(fileOutput); 
    int c; 
    while ((c = inputStream.read()) != -1) 
     fo.write(c); 
    fo.close(); 
    System.out.println("Blob retrieved"); 
+0

J'aurais dû être plus clair sur ce point: Le blob ne provient pas d'une requête, mais c'est un fichier zip qui est créé en lisant certains fichiers qui résident sur le serveur db. (Ce n'est pas le design le plus élégant, mais malheureusement nous devons travailler avec ça.) Par conséquent, je ne pense pas que ce que vous avez suggéré s'applique. –

+0

@inflagranti: Oh. Eh bien, vous allez probablement devoir écrire une classe qui implémente l'interface Blob. –