# Ein paar Fragen zur DB-Programmierung



## Gast (27. Jun 2005)

Hallo!

Ich bin noch nicht sehr erfahren in der DB-Programmierung und habe deshalb ein paar Fragen zur dazu:

(1) Ich habe mal gehört, dass PreparedStatements Vorteile gegenüber Statements haben, wenn man bestimmte Sonderzeichen in den zu speichernden/lesenden Daten hat. Stimmt das und warum ist das so?

(2) Gibt es bestimmte Richtlinien, wann man PreparedStatements und wann man Statements verwenden soll?

(3) Ändern von Daten: Ich habe eine Eingabemaske in der die Daten eingegeben und angezeigt werden können. D.h. die Eingabemaske spiegelt immer den aktuellsten Zustand eines Datensatzes wider. Wenn der Benutzer nun Daten ändert und diese speichern will, ist es dann sinnvoll den ganzen Datensatz zu löschen und neu anzulegen, oder sollte man die alten Daten mit den Neuen vergleichen und nur die Änderungen speichern? Diese Frage interessiert mich auch deshalb, weil man, im Prinzip ein PreparedStatement für jedes Datum der Tabelle brauchen würde, wenn man nur die Änderungen eines Datensatzes speichern will.

(4) Gibt es irgendwelche guten Tutorials im Netz, die sich mit den Konzepten (Best practices, etc) der Datenbankprogrammierung beschäftigen (die eben Fragen wie (3) beantworten)? Alles was ich bis jetzt gefunden habe, beschäftigt sich nur mit der Syntax von JDBC.


----------



## Bleiglanz (27. Jun 2005)

1) weil jede db etwas anderes mit literalen (datum, escape-sequenzen bei strings, ...) umgeht

und weil man dadurch gegen sql-injection etwas besser abgesichert ist

2) IMMER 

- wenn "dynamisch", d.h. der SQL-String zur Compilezeit nicht feststeht 

- wenn die Abfrage "mehrfach" ausgeführt wird und die DB und der Treiber eine entsprechende optimierung erlauben

ansonsten tuts auch ein fester SQL-String als normales Statement

3) NIE LÖSCHEN, DAS IST UNSINN

ob man bei einem UPDATE alle Spalten überschreibt (ist einfacher) oder nur die, die sich geändert haben (ist etwas aufwändiger) ist geschmackssache

Wenns Trigger o.ä. gibt, ist der zweite weg oft besser

4) http://www.google.com/search?client...l=en&q=jdbc+best+practices&btnG=Google+Search


----------



## Guest (27. Jun 2005)

Hallo!

Danke für die Antworten auf meine Fragen. Ich hab jetzt allerdings noch eine Frage zur Verwendung von Statements/PreparedStatements und ResultSets.

Ist es richtig, dass man bei der Verwendung von PreparedStatements diese beim Applikationsstart bzw. ersten Zugriff auf die DB erstellt und erst beim Programmende wieder schließt, während man Statements sofort nach dem Gebrauch wieder schliesst? Schließt man ResultSets auch gleich nach deren Verwendung? Etwa so:

```
Statement stmnt = null;
ResultSet res = null;
try
{
   res = stmnt.executeQuery("Select * FROM ......");
   // Verarbeite res
} finally
{
    if (stmnt != null) stmnt.close();
    if (res != null) res.close();
}
```


----------



## Bleiglanz (28. Jun 2005)

hängt davon ab, eher nein

am besten ist es, ALLES immer sofort wieder zu schliessen (und ggf. einen Connection-Pool verwenden); also eine Hit-And-Run Strategie

muss gut überlegt sein, wenn man irgendein mit der DB verbundenes Ding länger als 1 Minute "offen" hält...




```
Connection conn=null;
Statement st = null;
ResultSet rs = null;
try
{
    conn = X.getConnection); // X=?
    st = conn.createStatement();
    rs = st.executeQuery("...");
    //
    // jetzt ARBEITEN
    //
    rs.close();
    rs = null;
    st.close();
    st = null;
    conn.close();
    conn = null;
}
catch(SQLException e)
{
    // oder weiterwerfen
}
finally
{
    // wenn != null dann gabs nen Fehler
    if(rs!=null)
    {
      try{rs.close();}catch(Exception e){//meistens nix zu tun??}
    }
    if(st!=null)
    {
      try{st.close();}catch(Exception e){}
    }
    if(conn!=null)
    {
      try{conn.close();}catch(Exception e){}
    }
}
```


----------



## Guest (28. Jun 2005)

Danke für die Antwort. Das hat mir jetzt schon mal sehr geholfen.  :toll: 

Was mir allerdings noch nicht klar ist, ist ob man das mit PreparedStatements auch so machen soll wie mit normalen Statements? Denn wenn ich ein PreparedStatement erst in der Methode erzeuge in der es gebraucht wird, dann würde das ja mit jedem Aufruf dieser Methode erneut "vor-kompiliert" und der Vorteil von PreparedStatement doch wieder weg, oder sehe ich da was falsch?


----------



## Bleiglanz (28. Jun 2005)

im prinzip ja

hängt aber vom jdbc-treiber ab, ob er dieses statement nicht doch cached (eigentlich soll die vor-kompilierung in der DB stattfinden)

richtig sinn manchen die IMHO nur, wenn du schnell hintereinander mehrere Queriys absetzen musst, bei denen sich nur ein parameter ändert (clear - setString(1,"foo"); - clear - setString(1,"bar") usw.

schöner wärs natürlich

prepStatement öffenen

was tun

3 Minuten warten

nochmal was mit dem prep tun

nochmal 5 Minuten warten

usw.


=> aber wie schon gesagt, dass "offenhalten" von Connections ist etwas diffizil und muss sauber "ausprogrammiert" werden


----------



## Guest (28. Jun 2005)

Danke!


----------



## Bleiglanz (28. Jun 2005)

ähh, hab mich verschrieben

"richtig Sinn" machen prepStatements auch dann, wenn dynamisch Werte in einen SQL-String eingesetzt werden, weil dann das "Escapen" und "Quoten" vom Treiber übernommen wird

+ arbeitserleichterung
+ portabilität
+ sicherheit


----------



## Guest (28. Jun 2005)

Ok, danke für den Nachtrag.


----------



## pro_evo (28. Jun 2005)

kurze Frage:

Sind die PreparedStatements auch für SELECT Abfragen geeignet ?

Hab die nämlich nur bei Update Anweisungen gesehen ....


----------



## DP (28. Jun 2005)

Bleiglanz hat gesagt.:
			
		

> wenn du schnell hintereinander mehrere Queriys absetzen musst



wieviele sind _mehrere_?

thx


----------



## Guest (28. Jun 2005)

pro_evo hat gesagt.:
			
		

> kurze Frage:
> 
> Sind die PreparedStatements auch für SELECT Abfragen geeignet ?
> 
> Hab die nämlich nur bei Update Anweisungen gesehen ....


Ja.
z.B.
	
	
	
	





```
SELECT feld1, feld2, feld3...
FROM Tabelle
WHERE feld1 BETWEEN ? AND ?
  AND feld2 LIKE ?
  AND feld3 = ?
```


----------



## pro_evo (28. Jun 2005)

Anonymous hat gesagt.:
			
		

> pro_evo hat gesagt.:
> 
> 
> 
> ...




hmm sry aber den Code hab ich ned verstanden  ???:L

edit : sowas geht schomma ned ...

```
PreparedStatement ps = con.prepareStatement("Select ? FROM Mannschaft");
			ps.setString(1,"*");
			ResultSet rs = ps.executeQuery();
```


----------



## Guest (29. Jun 2005)

Der Platzhalter gelten nur für die WHERE-Klausel.
Das, was Du haben möchtest, kannst Du mit z.B.
java.text.MessageFormat oder auch, wenn's sein
muss, mit StringBuffer oder RegEx erreichen.


----------



## Guest (29. Jun 2005)

Anonymous hat gesagt.:
			
		

> ...Der Platzhalter gelten...


Ehmm.. ich meinte "Die Platzhalter", sonst ist es grammatisch zu krass. :wink:


----------



## Bleiglanz (29. Jun 2005)

DP hat gesagt.:
			
		

> Bleiglanz hat gesagt.:
> 
> 
> 
> ...



das wieviel ist ganz egal, solange es in einem Rutsch durchläuft

Ich meinte damit nur, dass man das preparedStatement beim "Sammeln von Ergebnissen" aus N Abfragen 

Query1 (mit Param1)
Query2 (mit Param2)
...
QueryN (mit ParamN)

sicher gut brauchen kann, solange zwischen den Abfragen nicht auf einen Mausklick / IO / irgendwas gewartet werden muss. In obigem Fall wäre aber wohl ein handgestricktes WHERE ..IN (...) besser 

BTW: ich nehme IMMER preparedStatements, wenn ein dynamischer Parameter drinsteckt (auch wenn ich das nur einmal brauche)


----------



## pro_evo (30. Jun 2005)

Anonymous hat gesagt.:
			
		

> Der Platzhalter gelten nur für die WHERE-Klausel.
> Das, was Du haben möchtest, kannst Du mit z.B.
> java.text.MessageFormat oder auch, wenn's sein
> muss, mit StringBuffer oder RegEx erreichen.



acho ok , und woran liegt das, macht der da evtl. Hochkommas mit rein der setString oder wie ?


----------



## Bleiglanz (30. Jun 2005)

ja (zumindest bei allen DBs die ich kenne)

ganz sicher kann man sich aber nie sein, weil es nicht möglich ist, den erzeugen SQL-String auszulesen

BTW hab ich das auch schon oft verflucht, wär halt so schön gewesen, wenn man beim 

```
ORDER BY ? ?
```
die Spalte und ein "ASC" oder "DESC" einfügen könnte

die spalte geht meistens, weil integers ja normalerweise nicht gequotet werden, aber das ASC oder DESC muss man sich dann immer mit Stringbearbeitung hinkleben


----------



## pro_evo (1. Jul 2005)

Alles klar ! thx



			
				Bleiglanz hat gesagt.:
			
		

> ganz sicher kann man sich aber nie sein, weil es nicht möglich ist, den erzeugen SQL-String auszulesen


oh genau danach hab ich die API letztens abgegrast,  aber nat. nix gefunden ...


----------

