PostgreSQL Prepared Statement

C

Camino

Gast
Hallo,

ich hab in meiner Anwendung den Zugriff auf die Datenbank-Tabellen bisher über SQL-Anweisungen gemacht und wollte nun auf PreparedStatements umsteigen. Dazu hab ich eine Methode, die vorher nur den SQL-Code übergeben bekommen hat, ein bisschen angepasst:
Java:
	protected void executeSQL2( String sql, Object[] values ) {
		
		PreparedStatement st = null;
		
		int z = 1;
		
		// DB-Verbindung holen
		Connection conn = DBConnection.getInstance();
						
		try {
			st = conn.prepareStatement( sql );
			
			for( Object obj : values ) {
				if( obj.getClass().isInstance( Integer.class ) )
					st.setInt( z, (Integer)obj);
				if( obj.getClass().isInstance( String.class ) )
					st.setString( z, (String)obj);
				
				z++;
			}

			st.executeUpdate();
			st.close();
		} catch ( SQLException e ) {
			e.printStackTrace();
		}
		
	}
Ich übergeb der Methode jetzt einmal einen String für das PreparedStatement:
Java:
String sql = "INSERT INTO anmerkungen (anmerkung_id, stamm_id, user_id, text, zeitstempel) values (DEFAULT, ?, ?, ?, ?);";
und ein Array Object[] values, in welchem die Werte gespeichert sind, welche die ? im Statement ersetzen sollen. In meiner Methode frage ich die Objekte in einer Schleife nach ihrer Klasse (Integer oder String) ab, erhöhe den Zähler z für den Parameter im PreparedStatement und nach der Schleife wird mit
Code:
st.executeUpdate()
das Statement ausgeführt.

Mein Array Object[] values sieht so aus:
Java:
Object[] values = { new Integer(anmerkung.getPersonID()), new Integer(anmerkung.getUserID()),
				new String(anmerkung.getText()), new String(timestamp) };

Doch nun bekomme ich immer die Fehlermeldung:
Code:
org.postgresql.util.PSQLException: Für den Parameter 1 wurde kein Wert angegeben.
Obwohl ich int z am Anfang auf 1 gesetzt habe und es in der Schleife hochzähle. Eine Testausgabe auf der Konsole hat mir z auch richtig hochgezählt.

Evtl. könnte es an dem DEFAULT legen. Wenn ich dort stattdessen eine Zahl (0 oder 1) eingebe, bekomme ich die gleiche Fehlermeldung. Wenn ich null eingebe, bekomme ich eine NPE.

Ich weiss nun nicht mehr weiter und bräuchte mal Hilfe. Hab ich irgendwas vergessen oder falsch geschrieben?

Viele Grüsse
Camino
 
S

SlaterB

Gast
wieso so kompliziert über PreparedStatement und z++ in einer Schleife nachdenken wenn du selber schon mögliche Fehler bei DEFAULT oder wer weiß wo vermutest

als aller erstes Java aus dem Fenster schmeißen und in einem SQL-Tool irgendeinen funktionierenden INSERT-Befehl suchen,
möglichst kurz, z.B.
INSERT INTO anmerkungen (anmerkung_id, textl) values (42, 'hi');
wenn das irgendwelchen NOT NULL und sonstigen Constraints widerspricht, dann eben längeres Statement (oder noch besser einfachere Test-Tabelle)

sobald ein SQL gefunden ist (vielleicht hast du das ja schon, du schreibst ja vom Wechsel zu PreparedStatement),
dann das SQL in Java erstmal als normales Statement prüfen, falls nicht schon geschehen und dann als einzelnes PreparedStatement:
Java:
PreparedStatement p = ..;
p.setInt(1,42);
p.setString(2,"hi");
oder ähnliches, keine unmenschlich komplizierten Variablen wie anmerkung.getPersonID(), keine Arrays, keine abgetrennte Methode und all die unbekannten möglichen Fehlerquellen sondern erstmal einfache Dinge ausprobieren,

vielleicht hast du auch das all schon, dann leider diese Informationen nicht gepostet und ich habe hier umsonst geschrieben,
ansonsten wäre es auf diesem Wege interessant, bis wohin alles funktioniert,
wenn das 42-hi-PreparedStatment in Java geht (zwischen den Tests den Platz in der DB immer wieder frei machen),
dann von dort aus modifizieren, z.B. wo immer nötig DEFAULT einbauen, gehts dann nicht mehr?

oder von einer funktionierenden Variante auf die Methode mit Object[] wechseln, aber immer noch 42 + hi übergeben,
kommt es dabei zu Fehlern?

ein weiterer Punkt wäe wiederum von den festen Parametern auf Programmwerte wie anmerkung.getPersonID() zu wechseln,
wenn es genau dabei zu Fehlern kommt kann man es dank dieses schrittweisen Vorgehens leichter eingrenzen,
wobei ein einfaches Loggen der Parameter genauso schnell helfen würde
 
Zuletzt bearbeitet von einem Moderator:
C

Camino

Gast
wieso so kompliziert über PreparedStatement und z++ in einer Schleife nachdenken wenn du selber schon mögliche Fehler bei DEFAULT oder wer weiß wo vermutest
Das war ja nur eine Vermutung, hat sich aber als nicht begründet erwiesen. An dem DEFAULT lag es nicht. Und vorher als normales Statement hatte es ja auch prima funktioniert. Aber ich hab den Fehler nun wohl gefunden. Ich weiss zwar noch nicht genau warum, aber es lag wohl an meiner Schleife:
Java:
			for( Object obj : values ) {
				if( obj.getClass().isInstance( Integer.class ) )
					st.setInt( z, (Integer)obj);
				if( obj.getClass().isInstance( String.class ) )
					st.setString( z, (String)obj);
				
				z++;
			}

Wenn ich nun die Zuweisungen zum PreparedStatement einzeln schreibe, dann funktioniert es:
Java:
			st.setInt(1, (Integer)values[0]);
			st.setInt(2, (Integer)values[1]);
			st.setString(3, (String)values[2]);

Das alles nochmal Schritt für Schritt zu reduzieren und durchzugehen hat jedenfalls geholfen. Deshalb danke für den Tipp.

Jetzt hab ich aber ein weiteres Problem. Und zwar hab ich in der Datenbank-Tabelle ja auch ein Timestamp-Feld. Dem PreparedStatement gebe ich das mit setTimestamp(int index, Timestamp timestamp). In meinem Objekt habe ich aber ein GregorianCalendar. Wie bringe ich das in einen Timestamp?

Viele Grüsse
Camino
 
S

SlaterB

Gast
java.util.Date und noch elementarer ein long-Wert als Millisekunden sind die elementarsten Darstellungen von Zeit in Java,

schau in beiden Klassen nach was du an Input übergeben kannst (Konstruktoren, set-Methoden), und welche anderen Formen du herausholen kannst (get-Methoden),
wobei das unabhängig vom long-Hinweis überall so gilt,

----
hast du denn jetzt was anderes als die Schleife/ das vorherige Problem geklärt? klingt ja mysteriös,
der zweite Code-Block mit direkter Werte-Zuweisung ist doch keine Lösung
 
C

Camino

Gast
java.util.Date und noch elementarer ein long-Wert als Millisekunden sind die elementarsten Darstellungen von Zeit in Java,

schau in beiden Klassen nach was du an Input übergeben kannst (Konstruktoren, set-Methoden), und welche anderen Formen du herausholen kannst (get-Methoden),
wobei das unabhängig vom long-Hinweis überall so gilt,
OK, danke, werde ich mir mal anschauen...

hast du denn jetzt was anderes als die Schleife/ das vorherige Problem geklärt? klingt ja mysteriös,
der zweite Code-Block mit direkter Werte-Zuweisung ist doch keine Lösung
Nee, Lösung ist das eigentlich keine, da ich ja meine Methode auch für andere Fälle verwenden wollte. Mit den normalen Statements hatte ich einfach nur den SQL-Befehl an die Methode übergeben. Mit den PreparedStatements sollten eigentlich ein String und ein Array mit Objekten übergeben werden und dann dynamisch die Werte zugewiesen werden. Ist denn an der Schleife irgendwas falsch? Oder an dem Casten der Objekte? Ich werde da noch ein bisschen rumprobieren, vielleicht komme ich ja noch drauf, woran es liegen könnte.

Camino
 
C

Camino

Gast
Die Umwandlung von GregorianCalendar nach Timestamp (SQL) hab ich jedenfalls schon mal hinbekommen:
Java:
st.setTimestamp( 4, new Timestamp( ((GregorianCalendar)values[3]).getTimeInMillis() ) );
Timestamp braucht im Konstruktor einen long-Wert, den ich mit getTimeInMillis() vom GregorianCalendar bekomme.
 
S

SlaterB

Gast
> Ist denn an der Schleife irgendwas falsch? Oder an dem Casten der Objekte?

hätte ich am Code einen Fehler erkannt, hätte ich es schon gesagt, prüfe doch ganz einfach was passiert,
welches if nicht durchlaufen wird oder doch und dann ohne Aktion darin usw.,

viele Möglichkeiten gibt es natürlich nicht und jetzt entkomme ich auch meiner Blindheit, korrekt lautet es:
if (Integer.class.isInstance(obj))

einen solchen Code testet man eben erstmal mit einem einzelnen Objekt in einer einfachen main-Methode,
nicht in einer komplizierten Schleife mit PreparedStatement usw.
 
C

Camino

Gast
> Ist denn an der Schleife irgendwas falsch? Oder an dem Casten der Objekte?

hätte ich am Code einen Fehler erkannt, hätte ich es schon gesagt, prüfe doch ganz einfach was passiert,
welches if nicht durchlaufen wird oder doch und dann ohne Aktion darin usw.,
Ja, war ich gerade dabei und hab festgestellt, dass die if nie durchlaufen werden. Deshalb dann auch der erklärbare Fehler, dass für den Parameter 1 kein Wert angegeben wurde.

]viele Möglichkeiten gibt es natürlich nicht und jetzt entkomme ich auch meiner Blindheit, korrekt lautet es:
if (Integer.class.isInstance(obj))
Ja, das war es. Also, gar kein Datenbank-Problem. So funktioniert es natürlich...

einen solchen Code testet man eben erstmal mit einem einzelnen Objekt in einer einfachen main-Methode,
nicht in einer komplizierten Schleife mit PreparedStatement usw.
Ja, muss ich mir mal angewöhnen, so etwas zu entkomplizieren und einfacher zu testen.

Vielen Dank für die Hilfe
Camino
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A JDBC Prepared Statement Autoincrement Datenbankprogrammierung 3
N Update Prepared Statement Fehler bei Argumenten Datenbankprogrammierung 3
N Prepared Statement mit unbekannter Anzahl von Where-Clauses Datenbankprogrammierung 30
L MySQL Prepared Statement batch langsamer als bulk insert? Datenbankprogrammierung 10
F Frage zu Prepared Statement Datenbankprogrammierung 2
D Problem: Prepared Statement (Insert) funktioniert nicht. Datenbankprogrammierung 3
G Mit Prepared Statement in MDB schreiben Datenbankprogrammierung 7
W Prepared Statement und Verbindungsverlust Datenbankprogrammierung 4
W Prepared Statement mehrere Zeichenketten Datenbankprogrammierung 4
G Keine Aussicht mit Prepared Statement Datenbankprogrammierung 10
P Prepared Statement scheint nicht zu funktionieren Datenbankprogrammierung 14
N Prepared Statement Datenbankprogrammierung 8
T Prepared Statements und Sets Datenbankprogrammierung 5
L Wiederverwendung von Prepared Statements Datenbankprogrammierung 4
Landei Mehre Werte für einen Prepared-Statement_Parameter übergeben? Datenbankprogrammierung 3
N prepared Statements Datenbankprogrammierung 6
G Flexible Prepared Statements Datenbankprogrammierung 2
F Update mit Prepared Statements Datenbankprogrammierung 10
T SQL-Statement Datenbank nach SQL Statement schließen? Datenbankprogrammierung 7
Kotelettklopfer SQLite Verhindern von doppelter Statement Ausführung Datenbankprogrammierung 25
L SQL-Statement SQL Statement doppelte Einträge finden Datenbankprogrammierung 9
C MySQL SQL Statement wir nicht ausgeführt Datenbankprogrammierung 11
G Datenbank Statement Datenbankprogrammierung 22
Dimax Erstellen ResultSet und Statement Datenbankprogrammierung 30
B MySQL Umkreissuche - brauche Hilfe bei SQL Statement Datenbankprogrammierung 12
M CSV Import - Dynamisches SQL Statement Datenbankprogrammierung 15
D Wiederverwendung / Recycling / Queuing von Statement Objekten Datenbankprogrammierung 1
D SQL Statement gesucht... Datenbankprogrammierung 15
J JDBC SQL Statement mit Parameter Datenbankprogrammierung 7
F Dynamischen String in SQL Statement einbinden Datenbankprogrammierung 9
L SQL Statement mit Switch-Case funktioniert nicht Datenbankprogrammierung 6
U PostgreSQL SELECT Statement Datenbankprogrammierung 5
A Problem mit Create-Statement Datenbankprogrammierung 9
LadyMilka MySQL Syntaxfehler im Statement Datenbankprogrammierung 3
P SQL-Statement Bei meinem Statement ist ein Fehler? Datenbankprogrammierung 2
P sql statement alter table foreign key Datenbankprogrammierung 4
T sql Statement Datenbankprogrammierung 9
B JDBC MySQL Statement Datenbankprogrammierung 3
A Sql Statement - Alle Zahlen größer 9 Datenbankprogrammierung 3
F Sql Statement Datenbankprogrammierung 12
A SQL-Statement prüfen Datenbankprogrammierung 3
W Statement als Klassenvariable Datenbankprogrammierung 27
I Select-Statement optimieren Datenbankprogrammierung 14
D SQLite Statement nimmt keine Namen aus getter-Methoden Datenbankprogrammierung 11
alex_fairytail MySQL SQL Statement Delete zwischen Datum1 und Datum2 Datenbankprogrammierung 5
M Access Update Statement Fehler update -> unmöglich? Datenbankprogrammierung 3
R Derby/JavaDB LIKE Statement mit Wildcard Datenbankprogrammierung 20
R Select Statement als temporärer Table Datenbankprogrammierung 7
R Derby/JavaDB Select Statement Where bedingung will nicht ganz! Datenbankprogrammierung 4
R Derby/JavaDB Select TOP Statement geht nicht Datenbankprogrammierung 3
S Null Pointer exception statement Datenbankprogrammierung 8
R Derby/JavaDB Insert Statement Probleme Datenbankprogrammierung 14
K statement.execute liefert false Datenbankprogrammierung 6
S SQL Statement: executeUpdate Datenbankprogrammierung 15
F wie funktioniert if Statement in SELECT? Datenbankprogrammierung 2
T MySQL PreparedStatement mit INSERTs langsam, Batch-Statement auch Datenbankprogrammierung 4
M MySQL größere von zwei Zahlen in Update Statement Datenbankprogrammierung 2
J [Hibernate] Select Statement Datenbankprogrammierung 4
S HSQLDB DELETE-Statement funktioniert nicht Datenbankprogrammierung 4
L MySQL Kann Statement nicht erzeugen Datenbankprogrammierung 5
T Komme mit dem SQL Statement nicht weiter Datenbankprogrammierung 5
D MySQL Client - Server: Client verabschiedet sich sobald ich Variablen im SQL Statement verwende Datenbankprogrammierung 9
T java.sql.SQLException: unexpected end of statement Datenbankprogrammierung 2
J SQL-Statement Datenbankprogrammierung 10
U MSSQL Verbindung steht, aber meckert beim Statement Datenbankprogrammierung 2
S executeBatch result immet mit Statement.SUCCESS_NO_INFO Datenbankprogrammierung 4
G Frage zum Insert-Statement Datenbankprogrammierung 2
J JDBC- Statement Ausführung nicht persistent Datenbankprogrammierung 2
A Connection Variable in anderer Klasse verwenden -> statement Datenbankprogrammierung 2
Z DELETE-Statement Datenbankprogrammierung 6
G INSERT-STATEMENT Datenbankprogrammierung 6
alexpetri hsql statement problem Datenbankprogrammierung 3
W invalid sql statement ? Datenbankprogrammierung 3
S Probleme mit statement.close() Datenbankprogrammierung 10
G Wie ein SQL-Statement zusammensetzen? Datenbankprogrammierung 5
T Select Statement auf Relation Datenbankprogrammierung 3
S Connection/Statement/ResultSet auf einmal geschlossen Datenbankprogrammierung 8
G MsSQL | Statement.execute(String s) Datenbankprogrammierung 3
G Für jede SQL-Abfrage eigenes Statement und ResultSet? Datenbankprogrammierung 3
C Statement/Connection SQLWarning Datenbankprogrammierung 4
J sql-statement Datenbankprogrammierung 7
G Update Statement automatisch unterteilen lassen Datenbankprogrammierung 3
T SQL-Statement parser? Datenbankprogrammierung 11
G Problem mit Suchen Statement Java und MS-SQL-Server Datenbankprogrammierung 9
J SELECT-Statement Datenbankprogrammierung 4
S Statement.getGeneratedKeys() funktioniert nicht Datenbankprogrammierung 4
G Problem mit Delete-Statement Datenbankprogrammierung 3
L mehrere Abfragen mit einem Statement!? Datenbankprogrammierung 5
E Problem mit create-Statement Datenbankprogrammierung 5
E SQL-Statement um eine Nummer in der Datenbank zu suchen Datenbankprogrammierung 3

Ähnliche Java Themen

Neue Themen


Oben