CashedRowSet update - oder was mache ich falsch -

Status
Nicht offen für weitere Antworten.

Seve

Mitglied
Hallo zusammen,

ich habe eine Frage, bzw ein im Moment schweriegendes Problem...

ich habe eine Array von CachedRowSets, die meine Datenbank wiederspiegeln.
Wenn ich jetzt eines updaten will, also eine Zeile in der lokalen kopie ändern möchte verwende ich da zu folgenden Schnipsel:

Code:
public static void update (int index, String [] zeile, int nr)
{
	/*
	 * Updatet die bezeichnete Zeile aus der Kopie der Tabelle 
	 */
	try
	{
		CRS [index].absolute(nr);
		for (int x = 0; x < zeile.length; x ++)
		{
			CRS [index].setString(x+1, zeile[x]);
		}
		CRS [index].updateRow();
		System.out.println (CRS [index].rowUpdated());
	}
	catch (SQLException e)
	{
		e.printStackTrace();
	}
	catch (ArrayIndexOutOfBoundsException e)
	{
		throw new IllegalArgumentException ("Der Tabellenindex ist unbekannt"«»);
	}
}

wobei zeile [] immer den komplettem Inhalt der Zeile enthält die geändert werden soll.

Das ergebnis ist: 1. es wird "false" ausgeben...
2. beim zurück schreiben in die Datenbank kommt folgender Stack:
java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3288)
at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3272)
at com.mysql.jdbc.PreparedStatement.setString(PreparedStatement.java:4108)
at com.mysql.jdbc.PreparedStatement.setObject(PreparedStatement.java:3527)
at com.sun.rowset.internal.CachedRowSetReader.decodeParams(Unknown Source)
at com.sun.rowset.internal.CachedRowSetReader.readData(Unknown Source)
at com.sun.rowset.CachedRowSetImpl.execute(Unknown Source)
at com.sun.rowset.internal.CachedRowSetWriter.commit(Unknown Source)
at com.sun.rowset.CachedRowSetImpl.acceptChanges(Unknown Source)
at com.sun.rowset.CachedRowSetImpl.acceptChanges(Unknown Source)
at dbaccess.DBAccess2.speichern(DBAccess2.java:132)
at dbaccess.DBAccess2.speichern(DBAccess2.java:106)
at dbaccess.tester.<init>(tester.java:17)
at gui.Main.main(Main.java:92)
javax.sql.rowset.spi.SyncProviderException: Parameter index out of range (1 > number of parameters, which is 0).
at com.sun.rowset.CachedRowSetImpl.acceptChanges(Unknown Source)
at com.sun.rowset.CachedRowSetImpl.acceptChanges(Unknown Source)
at dbaccess.DBAccess2.speichern(DBAccess2.java:132)
at dbaccess.DBAccess2.speichern(DBAccess2.java:106)
at dbaccess.tester.<init>(tester.java:17)
at gui.Main.main(Main.java:92)

Und hier noch die Mehtode in der die Exceptions auftauchen:
Code:
private static void speichern (int x)
{
	try
       {
		CRS [x].acceptChanges(gui.Main.conn);
	}
	catch (SQLException e)
	{
		e.printStackTrace();
	}
}

Ich hoffe, ich habe alles verständlich dargelegt und es gibt jemand der mir helfen kann.

Gruß Seve
 
muss man nicht wissen, was CRS ist?
wird das mit irgendeiner SQL-Abfrage gebildet?
was läßt dich davon ausgehen, dass es einen Parameter 1 gibt?
 
okay,

Code:
private static CachedRowSetImpl[] CRS  = null;

ist die Ursprüngliche Deklaration.

gefüllt wird das Array mittels der folgenden Methode und die wird auch definitiv aufgerufen:

Code:
public static void ladealle ()
	{
		try
		{
			ResultSet rs = gui.Main.conn.createStatement().executeQuery("show tables from lehrerverteilung");
			rs.last();
			int x = rs.getRow();
			rs.beforeFirst();
			namen = new String [x/2];
			int n = 0;
			while (rs.next())
			{
				String temp = rs.getString(1);
				if (!temp.contains("arbeit"))
				{
					namen[n] = temp;
					n++;
				}
			}
		}
		catch (SQLException e)
		{
			e.printStackTrace();
		}
		CRS = new CachedRowSetImpl [namen.length];
		for (int x = 0; x < namen.length; x++)
		{
			CRS [x] = lade (namen [x]);
		}
	}
	
	private static CachedRowSetImpl lade(String tabelle)
	{
		String query = "SELECT * FROM " + tabelle;
		try
		{
			CachedRowSetImpl temp = new CachedRowSetImpl ();
			temp.setCommand(query);
			temp.execute(gui.Main.conn);
			temp.setConcurrency(ResultSet.CONCUR_UPDATABLE );
			return temp;
		}
		catch (SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}

Zum Parameter:
Nun ja, ich wüsste ehrlich gesagt nicht, wie ich sonst die Spalte definieren sollte, von der der Wert geändert werden soll.

Gruß Seve
 
na gut, nach der API
http://java.sun.com/j2se/1.5.0/docs/api/javax/sql/rowset/CachedRowSet.html
scheinst du das ja richtig zu machen 😉

vielleicht hast du eine Tabelle dabei, die keine Spalten enthält?
du musst ja nicht gleich alle Tabellen der Datenbank auf einmal bearbeiten (show tables from),
such dir doch erstmal eine aus, gib die Spalten aus und versuche dort die Daten zu ändern und zurückzuspeichern,

wenn es mit einer Test-Tabelle geht, dann ausweiten,
und loggen, z.B. welche Tabellen es alles gibt mit wieviel Spalten welcher Datentypen usw.
 
Also ich habe noch was rum probiert. Ich habe es erstmal, wie du vorgeschlagen hast nur mit einer Tabelle genommen, von der ich weiß, dass sie gefüllt ist, knapp 30 Datensätze. Also habe ich über die Metadaten mir anzeigen lassen, was Java von der Tabelle hält.

Code:
System.out.println (tabelle);
System.out.println (metaData.getColumnCount());
for (int x = 1; x < metaData.getColumnCount()+1; x++)
{
	System.out.println (metaData.getColumnName(x));
	System.out.println (metaData.getColumnTypeName(x));				
}

dabei kommt raus:
klasse
3
index
INT
stufe
INT
ordnung
VARCHAR

Wenn ich in der Updatemethode so erweitere:

Code:
public static void update (int index, String [] zeile, int nr)
{
	/*
	 * Updatet die bezeichnete Zeile aus der Kopie der Tabelle 
	 */
	try
	{
		System.out.println ("update");
		CRS [index].absolute(nr);
		ResultSetMetaData metaData = CRS [index].getMetaData();
		for (int x = 0; x < zeile.length; x ++)
		{
			System.out.println (x+1);
			System.out.println (metaData.getColumnName(x+1));
			System.out.println (metaData.getColumnTypeName(x+1));
			System.out.println (zeile [x]);
			CRS [index].setString(x+1, zeile[x]);
		}
		CRS [index].updateRow();
		System.out.println (CRS [index].rowUpdated());
		
	}
	catch (SQLException e)
	{
		e.printStackTrace();
	}
	catch (ArrayIndexOutOfBoundsException e)
	{
		throw new IllegalArgumentException ("Der Tabellenindex ist unbekannt");
	}
}

kommt folgendes raus:
update
1
index
INT
5
2
stufe
INT
6
3
ordnung
VARCHAR
x

also kann es eigendlich nicht an der falschen Zeilenanzahl liegen. Es sei denn ich liege völlig daneben.


Ich habe es grade mal mit einer Tabelle nur mit Varchars versucht. da kommt dann keine Exception mehr, aber er updatet immer noch nicht, hier nochmal der OutPrint:
statistik
2
name
VARCHAR
wert
VARCHAR
update
1
name
VARCHAR
hans
2
wert
VARCHAR
meyer
false

Ich hoffe, das jemand ne Idee hat.
 
:autsch: :autsch:

ich habe den Fehler dann doch mittlerweile gefunden. 😳 😳

Code:
CRS [index].setString(x+1, zeile[x]);

Setzt den Wert der Spalte wohin gegen:

Code:
CRS [index].updateString(x+1, zeile[x]);

Den Spalteninhalt updatet, was ich ja die ganze Zeit wollte.

Wenn das keine Betriebsblindheit ist. Aber jetzt funktiniersts, danke SlaterB für deine Hinweise

Gruß Seve (nicht das letzte Mal blind zu Euch kommend)
 
hmm, das habe ich auch übersehen,
aber ich hätte komplette Beispiele aus Tutorials kopiert 😉
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben