# Problem beim Bilder speichern auf dem SQL Server 2000



## Lautsprecher (6. Dezember 2005)

Hallo,
ich habe ein FingerScanner an meinem PC angeschlossen. Ich möchte nun das eingescannte Bild auf meinem SQL Server speichern und dabei gibts Probleme:

Das Feld auf dem SQL Server heißt template und hat den Datentyp *image* Länge *16*

Als Fehlermeldung erhalte ich folgendes:

java.sql.SQLException: I/O Error: More data in stream than specified by length
	at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1038)
	at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:436)
	at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeUpdate(JtdsPreparedStatement.java:402)


Mein Programm-Code für den Insert sieht folgendermaßen aus:


```
protected final String sDbDrv = "net.sourceforge.jtds.jdbc.Driver";
/* Url der Datenbank eingeben */
protected final String sDbUrl =  "jdbc:jtds:sqlserver://SDEUTTPDISYS1:1433:WU_Daten";
protected final String sUsr = ""; 
/* Passwort (z.B. mysqlpwd): );*/
protected final String sPwd = "";

/* Befehle in der entsprechenen Methode zum Speichern bzw. Insert des Fingerabdrucks*/
dbConnection = DriverManager.getConnection(sDbUrl, sUsr, sPwd );
enrollStmt = dbConnection.prepareStatement("INSERT INTO abdruck(PersonalNr, Nachname, template) values('"+persnr1+"','"+name+"', ?)");
enrollStmt.setBinaryStream(1,new ByteArrayInputStream(template.getData()),template.getSize());
enrollStmt.executeUpdate();
```


----------



## elmato (6. Dezember 2005)

ALso ich kenne mich mit sowas nicht wirklich aus, aber die Fehlermeldung sieht so aus, das das Bild einfach zu gross ist, entweder änderst du die Länge in deiner tabelle, oder da gibt's glaube ich auch sowas wie BLOB(Binary Large Object B) vielleicht hilft dir das
mfg
elmato


----------



## Thomas Darimont (6. Dezember 2005)

Hallo!

  Also bei mir Funktioniert das Abspeichern eines 200kbyte grossen Bildes einwandfrei mit diesen Einstellungen...
  Tabelle: image
  Spalte: ID : int
  Spalte: imageData : image 16

```
/**
   * 
   */
  package de.tutorials;
  
  import java.awt.image.BufferedImage;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.InputStream;
  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.sql.Statement;
  
  import javax.imageio.ImageIO;
  import javax.swing.ImageIcon;
  import javax.swing.JFrame;
  import javax.swing.JLabel;
  
  import net.sourceforge.jtds.jdbcx.JtdsDataSource;
  
  /**
   * @author Tom
   * 
   */
  public class ImageDatabaseInteractionExample {
  
  	/**
  	 * @param args
  	 */
  	public static void main(String[] args) throws Exception {
  		Class.forName("net.sourceforge.jtds.jdbc.Driver");
  
  		JtdsDataSource dataSource = new JtdsDataSource();
  		dataSource.setServerName("localhost");
  		dataSource.setPortNumber(1433);
  		dataSource.setUser("foo");
  		dataSource.setPassword("bar");
  		dataSource.setDatabaseName("test");
  
  		Connection connection = dataSource.getConnection();
  
  		File file = new File("c:/desktop.jpg");
  		InputStream imageInputStream = new FileInputStream(file);
  		insertStreamData(connection, "INSERT INTO image VALUES (1,?)",
 				imageInputStream, (int) file.length(), 1);
  
  		BufferedImage image = ImageIO.read(readStreamData(connection,
 		 	"SELECT imageData FROM image WHERE id = 1", "imageData"));
  		
  		connection.close();
  		
  		JFrame frm = new JFrame("ImageDatabaseInteractionExample");
  		frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  		frm.add(new JLabel(new ImageIcon(image)));
  		frm.pack();
  		frm.setVisible(true);
  
  	}
  
  	private static InputStream readStreamData(Connection connection,
  			String sql, String imageColumnName) throws Exception {
  		Statement statement = null;
  		ResultSet resultSet = null;
  
  		try {
  			statement = connection.createStatement();
  			resultSet = statement.executeQuery(sql);
  
  			if (resultSet.next()) {
 				return resultSet.getBinaryStream(imageColumnName);
  			} else {
  				return null;
  			}
  		} finally {
  			if (statement != null) {
  				statement.close();
  			}
  			if (resultSet != null) {
  				resultSet.close();
  			}
  		}
  
  	}
  
  	private static void insertStreamData(Connection connection, String sql,
  			InputStream imageInputStream, int contentLength,
  			int imageColumnIndex) throws SQLException {
  		PreparedStatement preparedStatement = connection.prepareStatement(sql);
  		preparedStatement.setBinaryStream(imageColumnIndex, imageInputStream,
  				contentLength);
  		preparedStatement.execute();
  		preparedStatement.close();
  	}
  }
```
 
 .,..btw. auch wenn die Datenbank grundsätzlich erlaubt binäre Daten wie Bilder etc. zu speichern sollte man in der Regel jedoch davon Abstand nehmen...  außer vielleicht einem vereinfachtem Backup bringen binäre Daten IMHO keinen großen Vorteil. Man kann nicht nach ihnen Suchen, sie machen die Datenbank fett und träge...

  Gruss Tom


----------



## Lautsprecher (7. Dezember 2005)

Hallo,
ein "normales Bild" (jpg) abzuspeichern habe ich auch schon geschafft. Kann es
vielleicht daran liegen, das mein ByteArrayInputStream immer variabel ist?
Ist ist nämlich so, ich habe für den Fingerabdruck einen frei verfügbaren Code aus 
dem Internet in mein Programm eingebaut, der jedoch für Access-Anbindung optimiert war.
In Access ein OLE-Objekt anzulegen klappt auch einwandfrei.
Aber nochmal zurück: Je nach dem wie man den Finger auf den Scanner legt und wieviele Punkte von dem externen Programm ermittelt werden können (Punkte dienen zur Identifizierung), variert die Größe des Images.

Was komisch ist, in VB gibts beim Speichern auf den SQL-Server keine Probleme!


----------

