PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [java]sql Statement bearbeiten



juan_
29.05.2009, 15:41
Hallo beisammen,

Ich habe ein kleines Problem bei der Datenbankabfrage.
Gegeben sei ein Programm mit Textfeldern, Checkboxen und Comboboxen und einem SQL Statement.

Nehmen wir weiter an, dass ich bspw.
den Inhalt des Textfeldes in die Variable "text", den Inhalt der checkbox in "chk" und die Auswahl der Combobox in "cmb" gespeichert habe.

Wenn ich nun mein sql Befehl mit diesen Angaben versehen will, sähe er zB so aus:


sql =
"
Select * from Tabelle1
WHERE xyz=" + "'" + text + "'" + "
AND zyx=" + "'" + chk + "'" + "
AND abc=" + "'" + cmb + "'" + ";
(hoffe, dass das ein bisschen übersichtlicher ist ;))


Soo, was wäre aber, wenn die Felder nicht zwangsläufig aktiviert/beschrieben sein sollen? es geht hierbei um eine Art Filter, dass ich zB sage, dass er mir alle Tuple anzeigen soll, wo chk=true ist.

Wie setzt man sowas um?

Hoffe ihr wisst was ich meine;)

Merci

supersucker
29.05.2009, 15:52
sql =
"
Select * from Tabelle1
WHERE xyz=" + "'" + text + "'" + "
AND zyx=" + "'" + chk + "'" + "
AND abc=" + "'" + cmb + "'" + ";
(hoffe, dass das ein bisschen übersichtlicher ist ;))

[ Ich hoffe, du verträgst Kritik ]

Wenn ich sowas sehe....plain-text SQL-Abfragen im Quellcode.

Unwartbar, unleserlich und fehleranfällig hoch 10.

Wenn ich dein Auftraggeber wäre, würde ich sowas komplett zurückwandern lassen.

Für sowas nimmt man ein ORM-Framework wie z.b. Hibernate (zumindest in der Java-Welt).



Hoffe ihr wisst was ich meine

Ja, ich weiß was du meinst....:-)

Das ist aber eher ein "optionales Setzen von Bedingungen".

Das wirst du aber mit plain-text-SQL nicht hinkriegen, ohne das es ein ellenlanges "switch-case" oder "if-else"-Gemurkse wird.

Richtig "sauber" und übersichtlich geht das halt nur mit einem ORM-Framework, s.o.

Um dir noch ein Beispiel zu geben (kann dir keines in Hibernate geben, da ich Java + Hibernate schon lange nicht mehr benutzt habe):

So würde deine Abfrage in RubyonRails + ActiveRecord (ORM) aussehen:



scope = scope.scoped :select => "DISTINCT foo.*"
scope = scope.scoped :conditions => ["bla = ?", bla == "true"] if bla
scope = scope.scoped :conditions => ["blub = ?", blub == "true"] if blub


Fertig.

Fazit:

Du hast 2 Möglichkeiten:

1. Völliger Murks mit ellenlangem, nicht wartbarem Code
2. ORM

juan_
29.05.2009, 16:02
Hallo,
Danke für deine schnelle Antwort. Hibernate kann und werde ich mir mal bei Gelegenheit angucken. Noch muss das wohl über Murks laufen ;)

das Ganze soll natürlich nicht professionell werden und da ich erst seit 1 Woche mit java und db's spiele, werde ich wohl auf die unsaubere Lösung zurückgreifen. dachte nur, dass es vielleicht möglich (im SQL Statement) wäre zu sagen, "wenn Bedingung 1 = "", dann ist nicht das Feld leer, sondern die Bedingung einfach nicht aktiv".

Ciao

supersucker
29.05.2009, 16:16
Nein,

im SQL selber kannst du das nicht machen.

Du musst also, wie schon erwähnt, dir was mit Java zurechtbasteln.

Und glaub mir, wenn du sowas mal für viele Bedingungen brauchst, wirst du ganz schnell anfangen auf ORM umzusteigen.....:devil:

Fairerweise muss allerdings noch erwähnt werden, das du natürlich auch eine Stored-Procedure nehmen könntest, aber das wäre ein noch größeres Verbrechen.

juan_
29.05.2009, 18:34
Okay.
Ich riskiers' einfach ;)

Ich habe nur 4 Parameter, also passts schon. ich muss mir nur überlegen, wie ich die Anweisung gestallte. ist ja auch nicht so leicht, weil ich ja nicht jede mögliche Kombination abarbeiten will.

Wie gesagt, arbeite erst seit Kurzem damit..

Danke

supersucker
29.05.2009, 19:31
Ich glaube, du hast mich nicht ganz verstanden....:-)


Ich habe nur 4 Parameter, also passts schon. ich muss mir nur überlegen, wie ich die Anweisung gestallte. ist ja auch nicht so leicht, weil ich ja nicht jede mögliche Kombination abarbeiten will.


Genau das MUSST du aber machen in deiner jetzigen Konstellation.

Wobei dich natürlich nix davon abhält, dir Code zu schreiben, der dem code ähnelt, wie in einem ORM deiner Wahl verwendet wird.

Z.B. so in Pseudo-Code:


sql = 'Select * from Tabelle1 '
condArr = []
condArr.push('xyz=' + text ) if !( text == null)
condArr.push('zyx=' + chk ) if !( chk == null)
condArr.push('abc=' + cmb ) if !( cmb == null)
sql += 'where ' + condArr.join(' AND ') if condArr.size > 0
sql += ';'


Musst nur noch auf java adaptieren und du hast was du wolltest...:)

juan_
29.05.2009, 20:41
genau bei der Arraysache bin ich auch gerade. zum Glück kann ich auch Ruby, da brauch ich mir den Kopp nicht mehr selbst zerbrechen ;)

Danke
//edit:
kurze Zwsichenfrage: wo ist bei einer checkbox der Unterschied zwischen null und false?
//edit2:
achso, du willst ruby Programmierer sein? (null != nil ;))

saeckereier
29.05.2009, 22:31
Lies dir in der Doku mal durch wie man Prepared Statements benutzt. Du solltest dir NICHT angewöhnen, SQL Abfragen in der Art zusammenzubauen. Im Gegensatz zu supersucker denke ich man kann durchaus auch mal SQL Abfragen direkt skripten, aber wenn man das macht:
- Prepared Statements verwenden => über Platzhalter im SQL-Statement die Parameter setzen
- SQL Statements mit den Platzhaltern in Resource-Files auslagern. Es ist doof, sowas nachher im Code anpassen zu müssen, wenn sich die DB ändert.
.
.
.
EDIT (autom. Beitragszusammenführung) :
.
http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html

supersucker
29.05.2009, 22:55
achso, du willst ruby Programmierer sein? (null != nil )

Wer lesen kann, ist wie immer im Vorteil:

Ich zitiere mich selber:


Z.B. so in Pseudo-Code:

Das ist lustig, da helf ich Depp dir und muss mich dann noch beleidigen lassen.

Na dann, viel Erfolg noch.

juan_
30.05.2009, 03:00
Hey supersucker,
ich bin dir echt dankbar für die Hilfe, und wollte nur ein kleines Späßchen zum (fast) gelösten Problem machen. Ich dachte das Smiley am Ende hats verdeutlicht. Aber wenn nicht: Sorry, war echt nicht so gemeint.

saeckereier, auch dir danke. ich werds mir mal angucken. //edit: prepared statements kann wohl leider keine Selects

Gute Nacht