# Blob Element kopieren



## eolith421 (4. Nov 2009)

Hallo!
Ich hätte da eine Frage zum kopiere von Blobs. Ich muss in meinem Programm Daten aus einer Tabelle aus einer Datenbank auslesen darunter auch blob Elemente und diese dann in eine Tabelle in einer anderen Datenbank schreiben, also eigentlich ein Kopiervorgang. Nachdem Blob eigentlich auch nichts anderes als Text ist habe ich mir gedacht, dass eigentlich folgender Code funktionieren würde:


```
int dmisPatientenId = -1;
		String ehrQuery = null;
		String dmisQuery = null;
		ResultSet ehrResult = null;
		
		try {
			ehrQuery = "select * from stammdaten WHERE Sozialversicherungsnummer="+ehrSozialversicherungsnummer;
			ehrResult = ehrDb.executeSelect(ehrQuery);
			ehrResult.first();
			
			Blob imageBlob = ehrResult.getBlob(13);
			
			dmisQuery = "insert into stammdaten (Sozialversicherungsnummer, Nachname, Vorname, Geschlecht, Geburtsdatum, Strasse, Hausnummer, Ort, PLZ, Land, Telefon, Patientenfoto) " +
			"VALUES ('"+ehrResult.getLong(2)+"', '"+ehrResult.getString(3)+"', '"+ehrResult.getString(4)+"','"+ehrResult.getString(5)+"','"+ehrResult.getDate(6)+"','"+ehrResult.getString(7)+"','"+ehrResult.getInt(8)+"','"+ehrResult.getString(9)+"','"+ehrResult.getInt(10)+"','"+ehrResult.getString(11)+"','"+ehrResult.getString(12)+"','"+imageBlob+"')";
			dmisPatientenId = dmisDb.executeUpdate(dmisQuery);
			
			return dmisPatientenId;
		}
		catch(Exception e){
			return dmisPatientenId;
		}
```
Tut er aber nicht, es wird nur die Referenz zum Blob in die DB geschrieben aber nicht das Element. Wo liegt hier mein Gedankenfehler?


----------



## SlaterB (4. Nov 2009)

> Wo liegt hier mein Gedankenfehler? 

keine Beispiele angeschaut

Google
->
Inserting BLOB data through JDBC

-----

gut, dass imageBlob.toString() nur die Referenz zurückliefert und sowieso ein SQL-String
> insert into ... values(3,'test','[100.000 Bytes Blob]')
höchstwahrscheinlich keinen Sinn machen würde, hätte man auch durch Denken herausfinden können,
aber naja


----------



## eolith421 (4. Nov 2009)

Wenn ich einen SQL Dump von einer Tabelle mit Blobs mache kann ich mir die Dateien auch anschauen, wenn Sie auch nicht leserlich. Ich habe mir die Beispiele sehr wohl angeschaut, nur erschien es mir sehr umständlich zuerst einen File/Image  zu erstellen ehe ich es dann erneut in die andere DB schreiben muss.

Florian


----------



## FArt (4. Nov 2009)

> Nachdem Blob eigentlich auch nichts anderes als Text ist


Wie kommst du da drauf?


----------



## eolith421 (6. Nov 2009)

Auch auf die Gefahr wieder eine etwas unfreundliche Antwort zu bekommen  nochmals eine Frage dazu. Ist das also die richtige und einzige Vorgangsweise um ein Blob von Tabelle A nach Tabelle B zu kopieren:

1. Blob aus Tabelle A auslesen
2. Bild bzw. Datei erzeugen 
3. Datei mithilfe eines InputStream einlesen
4. Mithilfe von PreparedStatement das Blob einfügen

Meine Probleme sind folgende:
- Ich habe eine eigene DB Methode bei der ich einfach die sql Query als String übergebe und diese Methode die DB einträgt. Geht das vielleich auch als String?
- Ich erzeuge keine "temporären" Dateien sondern stelle die Bilder mithilfe eines Servlets dar, kann das Probleme machen?

Mir erscheint diese Vorgangsweise als extrem umständlich.

Gruß,
Florian


----------



## SlaterB (6. Nov 2009)

Daten gibts auch immer Stream-basiert, selbst wenn es 100 MB sind, braucht das Programm nicht mehr als paar KB speicher, wenn das Blob stückweise eingelesen und gleich wieder weitergereicht wird

obs ohne PreparedStatement geht, kann ich nicht sagen


----------



## DerEisteeTrinker (6. Nov 2009)

ähm ich will ja nicht altklug klingen, aber warum will man sich daten aus der db holen, die dann eh gleich wieder darin verschwinden. ich glaub jede "moderne" db kann auch ein "insert into" verbunden mit einem "select" und da wird das bestimmt nicht als referenz umhergeschoben. und die datenbank kann man ja auch mit angeben


----------



## Gast (7. Nov 2009)

DerEisteeTrinker hat gesagt.:


> ähm ich will ja nicht altklug klingen, aber warum will man sich daten aus der db holen, die dann eh gleich wieder darin verschwinden. ich glaub jede "moderne" db kann auch ein "insert into" verbunden mit einem "select" und da wird das bestimmt nicht als referenz umhergeschoben. und die datenbank kann man ja auch mit angeben



So eine unmoderne Datenbank wie Oracle beispielsweise nicht. Bei Blobs bleibt meist tatsächlich nur der umständliche und langsame doppelte Weg.


----------



## SlaterB (7. Nov 2009)

wenn es dieselbe DB ist, braucht man ein Blob doch eh kaum verschieben/ zwei mal,
dann würde ich eine Klasse (edit: Tabelle) um das Blob herum aufbauen und eher die anderen Elemente umbenennen/ Ids ändern, falls irgendwas zu 'verschieben' ist


----------



## Gast (7. Nov 2009)

Also man muss den Blob natürlich nicht interpretieren, aber man muss ihn schon fetchen und wieder einfügen. Je nach interface reichts evtl. einfach nen stream durchzureichen.


----------



## eolith421 (11. Nov 2009)

Hallo!
Danke für die rege Deiskussion. Um das mit den DBs zu klären folgendes: Die Anwendung ist ein Prototyp, d.h. wenn die Anwendung einmal funktioniert wird sie die Daten ohnehin nicht aus einer MySQl DB sich holen sondern aus einem anderen mir nicht bekannten Repository. Das heißt die Klasse die die Kopiervorgänge vom Repository in meine MySQL DB von der Anwendung kopiert müssen ohnehin angepasst werden. Ich will nur schauen, dass sie möglichst wenig anpassen müssen, daher keine insert & select Kombinationen. 

Um zurück zum Thema zu kommen, noch eine Frage:

Ich habe inzwischen das Blob in einen inputStream geladen, jetzt wollte ich nur nochmals fragen, eben wegen der Portabilität, ob ich den input Stream wirklich nur mit prepareStament in die DB schreiben kann oder auch eben mithilfe eines Strings welcher an die DB Klasse weitergegeben werden kann? Im Internet beziehen sich die Beispiele vorwiegend auf Oracle und ebene prepare Statement.

Vielen Dank!
Florian


----------



## eolith421 (11. Nov 2009)

Hallo!
Ich habe jetzt einmal versucht, das ganze mithilfe von preparedStatement zu realisieren. Nur leider bekomme ich eine Exception:

Exception in thread "main" java.lang.AbstractMethodError: com.mysql.jdbc.PreparedStatement.setBinaryStream(ILjava/io/InputStream;J)V
	at at.ac.uibk.dbis.server.application.session.CopySessionData.copyStammdatenFromEhr(CopySessionData.java:69)

Ich denke ich habe aber am Anfang noch was falsch. Mein Code schaut im Moment so aus:


```
InputStream in = null;
			Blob data = ehrResult.getBlob("Patientenfoto");
			in = data.getBinaryStream();
			
			
			/*BufferedImage image = null;
			Blob imageBlob = ehrResult.getBlob(13);
			InputStream is = imageBlob.getBinaryStream();
			image = ImageIO.read(is);
			*/
			
			dmisQuery = "insert into stammdaten (Sozialversicherungsnummer, Nachname, Vorname, Geschlecht, Geburtsdatum, Strasse, Hausnummer, Ort, PLZ, Land, Telefon, Patientenfoto) " +
			"VALUES ('"+ehrResult.getLong(2)+"', '"+ehrResult.getString(3)+"',
'"+ehrResult.getString(4)+"','"+ehrResult.getString(5)+"','"+ehrResult.getDate(6)+"','"
+ehrResult.getString(7)+"','"+ehrResult.getInt(8)+"','"+ehrResult.getString(9)+"','"+ehrResult.getInt(10)+"','"+ehrResult.getString(11)+"','"+ehrResult.getString(12)+"','?')";
			
			Connection conn = dmisDb.connect();
			PreparedStatement stmt = conn.prepareStatement(dmisQuery);
			stmt.setBinaryStream(13, in, data.length());
			stmt.execute();
		    conn.commit();
			
			//dmisPatientenId = dmisDb.executeUpdate(dmisQuery);
			
			return dmisPatientenId;
```

Erzeuge ich den InputStream richtig bzw. kann man diesen hier verwenden? Wie gesagt ich habe hier leider noch meine Probleme, im Internet gibt es zwar viele Seiten auf denen erklärt ist wie man eine Datei als Blob speichert, aber nicht wie man von Blob zu Blob kopiert.

Danke,
Florian


----------



## SlaterB (11. Nov 2009)

Google
->
z.B.
Inserting BLOB Values with setBinaryStream() Method


> There are 3 versions of the setBinaryStream() method, two of them were added as part of JDBC 4.0 (Java 1.6). Your JDBC driver may not support them:
> [..]


----------

