1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
|
<html>
<head>
<title>
Handbuch der Java-Programmierung, 5. Auflage
</title>
</head>
<body>
<a name="startofbody"></a>
<script language="JavaScript" src="hjp4lib.js">
</script>
<script language="JavaScript">
installKbdHandler("97,#startofbody;101,#endofbody;116,cover.html;122,k100003.html;115,search.html;105,index.html;100,JDKDOCS;112,APIDOCS;104,k100265.html;106,k100268.html;107,k100270.html;108,k100271.html");
</script>
<table border=0 cellpadding=0 cellspacing=1 width="100%">
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
<td align="right">Handbuch der Java-Programmierung, 5. Auflage
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100265.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100268.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100270.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100271.html"> >> </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
<td align="right">Kapitel 42 - Datenbankzugriffe mit JDBC
</table>
<hr>
<!-- Section -->
<a name="sectlevel2id042004"></a>
<h2>42.4 Weiterführende Themen </h2>
<hr>
<ul>
<li><a href="k100269.html#sectlevel2id042004">42.4 Weiterführende Themen</a>
<ul>
<li><a href="k100269.html#sectlevel3id042004001">42.4.1 Metadaten</a>
<li><a href="k100269.html#sectlevel3id042004002">42.4.2 Escape-Kommandos</a>
<li><a href="k100269.html#subsectiontransaktionen">42.4.3 Transaktionen</a>
<li><a href="k100269.html#sectlevel3id042004004">42.4.4 JDBC-Datentypen</a>
<li><a href="k100269.html#jdbcobjekte">42.4.5 Umgang mit JDBC-Objekten</a>
<li><a href="k100269.html#sectlevel3id042004006">42.4.6 Prepared Statements</a>
<li><a href="k100269.html#sectlevel3id042004007">42.4.7 SQL-Kurzreferenz</a>
<ul>
<li><a href="k100269.html#sectlevel4id042004007001">Ändern von Datenstrukturen</a>
<li><a href="k100269.html#sectlevel4id042004007002">Ändern von Daten</a>
<li><a href="k100269.html#sectlevel4id042004007003">Lesen von Daten</a>
</ul>
</ul>
</ul>
<hr>
<p>
In diesem Abschnitt wollen wir eine Reihe von Themen ansprechen, die
bei der bisherigen Darstellung zu kurz gekommen sind. Aufgrund des
beschränkten Platzes werden wir jedes Thema allerdings nur kurz
ansprechen und verweisen für genauere Informationen auf die JDBC-Beschreibung
(sie ist Bestandteil der seit dem JDK 1.2 ausgelieferten Online-Dokumentation)
und auf weiterführende Literatur zum Thema JDBC.
<!-- Section -->
<a name="sectlevel3id042004001"></a>
<h3>42.4.1 Metadaten </h3>
<p>
In <a href="k100268.html#verbindungherstellen">Abschnitt 42.3.3</a>
sind wir bereits kurz auf die Verwendung von Metadaten eingegangen.
Neben den Datenbankmetadaten gibt es die Methode <a name="ixa103106"><a href="index_g.html#ixb102279"><font color=#000080><tt>getMetaData</tt></font></a></a>
der Klasse <a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
ResultSetMetaData getMetaData()
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/sql/ResultSet.html" onClick="this.href=getApiDoc('java.sql.ResultSet')"><font color="#660066" size=-1>java.sql.ResultSet</font></a></td>
</tr>
</table>
<p>
Sie liefert ein Objekt vom Typ <a name="ixa103107"><a href="index_r.html#ixb102283"><font color=#000080><tt>ResultSetMetaData</tt></font></a></a>,
das Meta-Informationen über die Ergebnismenge zur Verfügung
stellt. Wichtige Methoden sind:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
int getColumnCount()
String getColumnName(int column)
String getTableName(int column)
int getColumnType(int column)
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/sql/ResultSetMetaData.html" onClick="this.href=getApiDoc('java.sql.ResultSetMetaData')"><font color="#660066" size=-1>java.sql.ResultSetMetaData</font></a></td>
</tr>
</table>
<p>
Mit <a name="ixa103108"><a href="index_g.html#ixb102063"><font color=#000080><tt>getColumnCount</tt></font></a></a>
kann die Anzahl der Spalten in der Ergebnismenge abgefragt werden.
<a name="ixa103109"><a href="index_g.html#ixb102071"><font color=#000080><tt>getColumnName</tt></font></a></a>
und <a name="ixa103110"><a href="index_g.html#ixb102284"><font color=#000080><tt>getTableName</tt></font></a></a>
liefern den Namen der Spalte bzw. den Namen der Tabelle, zu der diese
Spalte in der Ergebnismenge gehört, wenn man ihren numerischen
Index angibt. Mit <a name="ixa103111"><a href="index_g.html#ixb102285"><font color=#000080><tt>getColumnType</tt></font></a></a>
kann der Datentyp einer Spalte abgefragt werden. Als Ergebnis wird
eine der statischen Konstanten aus der Klasse <a name="ixa103112"><a href="index_t.html#ixb102286"><font color=#000080><tt>java.sql.Types</tt></font></a></a>
zurückgegeben.
<!-- Section -->
<a name="sectlevel3id042004002"></a>
<h3>42.4.2 Escape-Kommandos </h3>
<p>
Mit den <a name="ixa103113"><i>Escape-Kommandos</i></a> wurde ein
Feature eingeführt, das die Portierbarkeit von Datenbankanwendungen
verbessern soll. In Anlehnung an ODBC fordert die JDBC-Spezifikation
dazu, dass die JDBC-Treiber in der Lage sein müssen, <i>besondere</i>
Zeichenfolgen in SQL-Anweisungen zu erkennen und in die spezifische
Darstellung der jeweiligen Datenbank zu übersetzen. Auf diese
Weise können beispielsweise Datums- und Zeitliterale portabel
übergeben oder eingebaute Funktionen aufgerufen werden. Die Escape-Kommandos
haben folgende Syntax:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
"{" <Kommandoname> [<Argumente>] "}"
</pre>
</font>
</td>
</tr>
</table>
<p>
Am Anfang steht eine geschweifte Klammer, dann folgen der Name des
Escape-Kommandos und mögliche Argumente, und am Ende wird das
Kommando durch eine weitere geschweifte Klammer abgeschlossen.
<p>
Um beispielsweise unabhängig von seiner konkreten Darstellung
einen Datumswert einzufügen, kann das Escape-Kommando »d«
verwendet werden. Es erwartet als Argument eine SQL-Zeichenkette im
Format »yyyy-mm-dd« und erzeugt daraus das zur jeweiligen
Datenbank passende Datumsliteral. In <a href="k100268.html#tabellenfuellen">Listing 42.5</a>
haben wir dieses Kommando verwendet, um das Änderungsdatum der
Datei in die Tabelle <i>file</i> zu schreiben.
<!-- Section -->
<a name="subsectiontransaktionen"></a>
<h3>42.4.3 <a name="ixa103114">Transaktionen</a></h3>
<p>
Die drei Methoden <a name="ixa103115"><a href="index_c.html#ixb102289"><font color=#000080><tt>commit</tt></font></a></a>,
<a name="ixa103116"><a href="index_r.html#ixb102290"><font color=#000080><tt>rollback</tt></font></a></a>
und <a name="ixa103117"><a href="index_s.html#ixb102291"><font color=#000080><tt>setAutoCommit</tt></font></a></a>
des <a href="index_c.html#ixb102245"><font color=#000080><tt>Connection</tt></font></a>-Objekts
steuern das Transaktionsverhalten der Datenbank:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
void commit()
void rollback()
void setAutoCommit(boolean autoCommit)
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/sql/Connection.html" onClick="this.href=getApiDoc('java.sql.Connection')"><font color="#660066" size=-1>java.sql.Connection</font></a></td>
</tr>
</table>
<p>
Nach dem Aufbauen einer JDBC-Verbindung ist die Datenbank (gemäß
JDBC-Spezifikation) zunächst im <a name="ixa103118"><i>Auto-Commit-Modus</i></a>.
Dabei gilt jede einzelne Anweisung als separate Transaktion, die nach
Ende des Kommandos automatisch bestätigt wird. Durch Aufruf von
<a href="index_s.html#ixb102291"><font color=#000080><tt>setAutoCommit</tt></font></a>
und Übergabe von <a href="index_f.html#ixb100234"><font color=#000080><tt>false</tt></font></a>
kann das geändert werden. Danach müssen alle Transaktionen
explizit durch Aufruf von <a href="index_c.html#ixb102289"><font color=#000080><tt>commit</tt></font></a>
bestätigt bzw. durch <a href="index_r.html#ixb102290"><font color=#000080><tt>rollback</tt></font></a>
zurückgesetzt werden. Nach dem Abschluss einer Transaktion beginnt
automatisch die nächste.
<p>
Wichtig ist auch der <a name="ixa103119"><i>Transaction Isolation Level</i></a>,
mit dem der Grad der Parallelität von Datenbanktransaktionen
gesteuert wird. Je höher der Level, desto weniger Konsistenzprobleme
können durch gleichzeitigen Zugriff mehrerer Transaktionen auf
dieselben Daten entstehen. Um so geringer ist aber auch der Durchsatz
bei einer großen Anzahl von gleichzeitigen Zugriffen. Transaction
Isolation Levels werden von der Datenbank üblicherweise mit Hilfe
von gemeinsamen und exklusiven Sperren realisiert. JDBC unterstützt
die folgenden Levels:
<ul>
<li><a name="ixa103120"><a href="index_t.html#ixb102294"><font color=#000080><tt>Connection.TRANSACTION_NONE</tt></font></a></a>
<li><a name="ixa103121"><a href="index_t.html#ixb102295"><font color=#000080><tt>Connection.TRANSACTION_READ_UNCOMMITTED</tt></font></a></a>
<li><a name="ixa103122"><a href="index_t.html#ixb102296"><font color=#000080><tt>Connection.TRANSACTION_READ_COMMITTED</tt></font></a></a>
<li><a name="ixa103123"><a href="index_t.html#ixb102297"><font color=#000080><tt>Connection.TRANSACTION_REPEATABLE_READ</tt></font></a></a>
<li><a name="ixa103124"><a href="index_t.html#ixb102298"><font color=#000080><tt>Connection.TRANSACTION_SERIALIZABLE</tt></font></a></a>
</ul>
<p>
Mit Hilfe der beiden Methoden <a name="ixa103125"><a href="index_g.html#ixb102299"><font color=#000080><tt>getTransactionIsolation</tt></font></a></a>
und <a name="ixa103126"><a href="index_s.html#ixb102300"><font color=#000080><tt>setTransactionIsolation</tt></font></a></a>
des <a href="index_c.html#ixb102245"><font color=#000080><tt>Connection</tt></font></a>-Objekts
kann der aktuelle Transaction Isolation Level abgefragt bzw. verändert
werden:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
int getTransactionIsolation()
void setTransactionIsolation(int level)
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/sql/Connection.html" onClick="this.href=getApiDoc('java.sql.Connection')"><font color="#660066" size=-1>java.sql.Connection</font></a></td>
</tr>
</table>
<p>
Mit der Methode <a name="ixa103127"><a href="index_s.html#ixb102301"><font color=#000080><tt>supportsTransactionIsolationLevel</tt></font></a></a>
des <a href="index_d.html#ixb102280"><font color=#000080><tt>DatabaseMetaData</tt></font></a>-Objekts
kann abgefragt werden, ob eine Datenbank einen bestimmten Transaction
Isolation Level unterstützt oder nicht.
<!-- Section -->
<a name="sectlevel3id042004004"></a>
<h3>42.4.4 JDBC-Datentypen </h3>
<p>
In den meisten Fällen braucht man keine <i>exakte</i> Kenntnis
des Datentyps einer Tabellenspalte, wenn man diese abfragt. Die oben
beschriebenen <font color="#000077"><tt>get</tt></font>-Methoden des
<a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>-Objekts
führen geeignete Konvertierungen durch. Soll dagegen mit <font color="#000077"><tt>CREATE
TABLE</tt></font> eine neue Datenbank definiert werden, muss zu jeder
Spalte der genaue Datentyp angegeben werden. Leider unterscheiden
sich die Datenbanken bezüglich der unterstützten Typen erheblich,
und die <font color="#000077"><tt>CREATE TABLE</tt></font>-Anweisung
ist wenig portabel. Die Klasse <a href="index_t.html#ixb102286"><font color=#000080><tt>java.sql.Types</tt></font></a>
listet alle JDBC-Typen auf und gibt für jeden eine symbolische
Konstante an. Mit der Methode <a name="ixa103128"><a href="index_g.html#ixb102302"><font color=#000080><tt>getTypeInfo</tt></font></a></a>
der Klasse <a href="index_d.html#ixb102280"><font color=#000080><tt>DatabaseMetaData</tt></font></a>
kann ein <a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>
mit allen Typen der zugrunde liegenden Datenbank und ihren spezifischen
Eigenschaften beschafft werden. In <a href="k100269.html#sqldatentypen">Tabelle 42.4</a>
findet sich eine Übersicht der wichtigsten SQL-Datentypen.
<!-- Section -->
<a name="jdbcobjekte"></a>
<h3>42.4.5 Umgang mit JDBC-Objekten </h3>
<p>
Wie zuvor erwähnt, sind die JDBC-Objekte des Typs <a href="index_c.html#ixb102245"><font color=#000080><tt>Connection</tt></font></a>
und <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>
möglicherweise kostspielig bezüglich ihres Rechenzeit- oder
Speicherverbrauchs. Es empfiehlt sich daher, nicht unnötig viele
von ihnen anzulegen.
<p>
Während das bei <a href="index_c.html#ixb102245"><font color=#000080><tt>Connection</tt></font></a>-Objekten
einfach ist, kann es bei <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekten
unter Umständen problematisch werden. Wird beispielsweise in
einer Schleife mit vielen Durchläufen immer wieder eine Methode
aufgerufen, die eine Datenbankabfrage durchführt, so stellt sich
die Frage, woher sie das dafür erforderliche <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekt
nehmen soll. Wird es jedesmal lokal angelegt, kann schnell der Speicher
knapp werden. Wird es dagegen als statische oder als Klassenvariable
angelegt, kann es zu Konflikten mit konkurrierenden Methoden kommen
(die üblichen Probleme globaler Variablen).
<p>
Eine gut funktionierende Lösung für dieses Problem besteht
darin, <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekte
auf der <a href="index_c.html#ixb102245"><font color=#000080><tt>Connection</tt></font></a>
zu <i>cachen</i>, also zwischenzuspeichern. Das kann etwa mit einer
Queue erfolgen, in die nicht mehr benötigte <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekte
eingestellt werden. Anstelle eines Aufrufs von <a href="index_c.html#ixb102248"><font color=#000080><tt>createStatement</tt></font></a>
wird dann zunächst in der Queue nachgesehen, ob ein recyclebares
Objekt vorhanden ist, und dieses gegebenenfalls wiederverwendet. Es
sind dann zu keinem Zeitpunkt mehr <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekte
angelegt, als <i>parallel</i> benötigt werden. Natürlich
dürfen nur Objekte in die Queue gestellt werden, die nicht mehr
benötigt werden; ihr <a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>
sollte also vorher möglichst geschlossen werden. Das <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekt
selbst darf nicht geschlossen werden, wenn es noch verwendet werden
soll.
<p>
Ein einfache Implementierung wird in dem folgendem Listing vorgestellt.
Das Objekt vom Typ <font color="#000077"><tt>CachedConnection</tt></font>
wird mit einem <a href="index_c.html#ixb102245"><font color=#000080><tt>Connection</tt></font></a>-Objekt
instanziert. Die Methoden <font color="#000077"><tt>getStatement</tt></font>
und <font color="#000077"><tt>releaseStatement</tt></font> dienen
dazu, <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekte
zu beschaffen bzw. wieder freizugeben.
<a name="listingid042011"></a>
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
<tr>
<td valign=top>
<font color="#000055">
<pre>
<font color="#555555">001 </font><font color="#00AA00">/* CachedConnection.java */</font>
<font color="#555555">002 </font>
<font color="#555555">003 </font><font color="#0000AA">import</font> java.sql.*;
<font color="#555555">004 </font><font color="#0000AA">import</font> java.util.*;
<font color="#555555">005 </font>
<font color="#555555">006 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> CachedConnection
<font color="#555555">007 </font>{
<font color="#555555">008 </font> <font color="#0000AA">private</font> Connection con;
<font color="#555555">009 </font> <font color="#0000AA">private</font> LinkedList<Statement> cache;
<font color="#555555">010 </font> <font color="#0000AA">private</font> <font color="#006699">int</font> stmtcnt;
<font color="#555555">011 </font>
<font color="#555555">012 </font> <font color="#0000AA">public</font> CachedConnection(Connection con)
<font color="#555555">013 </font> {
<font color="#555555">014 </font> <font color="#006699">this</font>.con = con;
<font color="#555555">015 </font> <font color="#006699">this</font>.cache = <font color="#0000AA">new</font> LinkedList<Statement>();
<font color="#555555">016 </font> <font color="#006699">this</font>.stmtcnt = 0;
<font color="#555555">017 </font> }
<font color="#555555">018 </font>
<font color="#555555">019 </font> <font color="#0000AA">public</font> Statement getStatement()
<font color="#555555">020 </font> <font color="#0000AA">throws</font> SQLException
<font color="#555555">021 </font> {
<font color="#555555">022 </font> <font color="#0000AA">if</font> (cache.size() <= 0) {
<font color="#555555">023 </font> <font color="#0000AA">return</font> con.createStatement();
<font color="#555555">024 </font> } <font color="#0000AA">else</font> {
<font color="#555555">025 </font> <font color="#0000AA">return</font> cache.poll();
<font color="#555555">026 </font> }
<font color="#555555">027 </font> }
<font color="#555555">028 </font>
<font color="#555555">029 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> releaseStatement(Statement statement)
<font color="#555555">030 </font> {
<font color="#555555">031 </font> cache.add(statement);
<font color="#555555">032 </font> }
<font color="#555555">033 </font>}</pre>
</font>
</td>
<td valign=top align=right>
<a href="../examples/CachedConnection.java"><font color="#000055" size=-1>CachedConnection.java</font></a></td>
</tr>
</table>
<i>
Listing 42.11: Die Klasse CachedConnection</i></p>
<p>
Es ist wichtig, die JDBC-Objekte auch dann zu schließen, wenn
eine Ausnahme während der Bearbeitung aufgetreten ist. Andernfalls
würden möglicherweise Ressourcen nicht freigegeben und das
Programm würde so nach und nach mehr Speicher oder Rechenzeit
verbrauchen. Am einfachsten kann dazu die <a href="index_f.html#ixb100579"><font color=#000080><tt>finally</tt></font></a>-Klausel
der <a href="index_t.html#ixb100569"><font color=#000080><tt>try</tt></font></a>-<a href="index_c.html#ixb100570"><font color=#000080><tt>catch</tt></font></a>-Anweisung
verwendet werden.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=1></td>
<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>
<p>
Eine weitere Eigenschaft der Klasse <a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>
verdient besondere Beachtung. Bei manchen JDBC-Treibern erlauben die
zurückgegebenen <a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>-Objekte
das Lesen einer bestimmten Tabellenspalte nur einmal. Der zweite Versuch
wird mit einer Fehlermeldung »No data« (oder ähnlich)
quittiert. Manche Treiber erfordern sogar, dass die Spalten des <a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>
in der Reihenfolge ihrer Definition gelesen werden. In beiden Fällen
ist es gefährlich, einen <a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>
als Parameter an eine Methode zu übergeben, denn die Methode
weiß nicht, welche Spalten bereits vom Aufrufer gelesen wurden
und umgekehrt. Eine Lösung könnte darin bestehen, einen
<a href="index_r.html#ixb102252"><font color=#000080><tt>ResultSet</tt></font></a>
mit integriertem Cache zu entwickeln, der sich bereits gelesene Spaltenwerte
merkt. Alternativ könnte man auch einen objekt-relationalen Ansatz
versuchen, bei dem jeder gelesene Satz der Ergebnismenge direkt ein
passendes Laufzeitobjekt erzeugt, das dann beliebig oft gelesen werden
kann. Wir wollen auf beide Varianten an dieser Stelle nicht weiter
eingehen.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#CC0000">
<tr>
<td><font color="#FFFFFF"> Warnung </font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
</tr>
</table>
<!-- Section -->
<a name="sectlevel3id042004006"></a>
<h3>42.4.6 Prepared Statements </h3>
<p>
<a name="ixa103129"><i>Prepared Statements</i></a> sind parametrisierte
SQL-Anweisungen. Sie werden zunächst deklariert und zum Vorkompilieren
an die Datenbank übergeben. Später können sie dann
beliebig oft ausgeführt werden, indem die formalen Parameter
durch aktuelle Werte ersetzt werden und die so parametrisierte Anweisung
an die Datenbank übergeben wird. Der Vorteil von Prepared Statements
ist, dass die Vorbereitungsarbeiten nur einmal erledigt werden müssen
(Syntaxanalyse, Vorbereitung der Abfragestrategie und -optimierung)
und die tatsächliche Abfrage dann wesentlich schneller ausgeführt
werden kann. Das bringt Laufzeitvorteile bei der wiederholten Ausführung
der vorkompilierten Anweisung.
<p>
JDBC stellt Prepared Statements mit dem Interface <a name="ixa103130"><a href="index_p.html#ixb102304"><font color=#000080><tt>PreparedStatement</tt></font></a></a>,
das aus <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>
abgeleitet ist, zur Verfügung. Die Methode <a name="ixa103131"><a href="index_p.html#ixb102305"><font color=#000080><tt>prepareStatement</tt></font></a></a>
des <a href="index_c.html#ixb102245"><font color=#000080><tt>Connection</tt></font></a>-Objekts
liefert ein <a href="index_p.html#ixb102304"><font color=#000080><tt>PreparedStatement</tt></font></a>:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public PreparedStatement prepareStatement(String sql)
throws SQLException
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/sql/Connection.html" onClick="this.href=getApiDoc('java.sql.Connection')"><font color="#660066" size=-1>java.sql.Connection</font></a></td>
</tr>
</table>
<p>
Als Argument wird ein String übergeben, der die gewünschte
SQL-Anweisung enthält. Die formalen Parameter werden durch Fragezeichen
dargestellt. Bei den meisten Datenbanken dürfen sowohl Änderungs-
als auch Abfrageanweisungen vorkompiliert werden. Sie werden dann
später mit <a href="index_e.html#ixb102249"><font color=#000080><tt>executeQuery</tt></font></a>
bzw. <a href="index_e.html#ixb102250"><font color=#000080><tt>executeUpdate</tt></font></a>
ausgeführt. Anders als im Basisinterface sind diese Methoden
im Interface <a href="index_p.html#ixb102304"><font color=#000080><tt>PreparedStatement</tt></font></a>
parameterlos:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public ResultSet executeQuery()
throws SQLException
public int executeUpdate()
throws SQLException
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/sql/PreparedStatement.html" onClick="this.href=getApiDoc('java.sql.PreparedStatement')"><font color="#660066" size=-1>java.sql.PreparedStatement</font></a></td>
</tr>
</table>
<p>
Bevor eine dieser Methoden aufgerufen werden darf, ist es erforderlich,
die vorkompilierte Anweisung zu parametrisieren. Dazu muss für
jedes Fragezeichen eine passende <font color="#000077"><tt>set</tt></font>-Methode
aufgerufen und das gewünschte Argument übergeben werden.
Die <font color="#000077"><tt>set</tt></font>-Methoden gibt es für
alle JDBC-Typen (siehe beispielsweise die analoge Liste der <font color="#000077"><tt>get</tt></font>-Methoden
in <a href="k100267.html#resultsetgetmethoden">Tabelle 42.1</a>):
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public void setBoolean(int parameterIndex, boolean x)
throws SQLException
public void setByte(int parameterIndex, byte x)
throws SQLException
...
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/sql/PreparedStatement.html" onClick="this.href=getApiDoc('java.sql.PreparedStatement')"><font color="#660066" size=-1>java.sql.PreparedStatement</font></a></td>
</tr>
</table>
<p>
Der erste Parameter gibt die Position des Arguments in der Argumentliste
an. Das erste Fragezeichen hat den Index 1, das zweite den Index 2
usw. Der zweite Parameter liefert den jeweiligen Wert, der anstelle
des Fragezeichens eingesetzt werden soll.
<p>
Als Beispiel wollen wir uns eine abgewandelte Form der in <a href="k100268.html#zaehlenverzdateien">Abschnitt 42.3.5</a>
vorgestellten Methode <font color="#000077"><tt>countRecords</tt></font>
ansehen, bei der anstelle eines <a href="index_s.html#ixb102247"><font color=#000080><tt>Statement</tt></font></a>-Objekts
ein <a href="index_p.html#ixb102304"><font color=#000080><tt>PreparedStatement</tt></font></a>
verwendet wird:
<a name="listingid042012"></a>
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
<tr>
<td valign=top>
<font color="#000055">
<pre>
<font color="#555555">001 </font><font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> countRecords()
<font color="#555555">002 </font><font color="#0000AA">throws</font> SQLException
<font color="#555555">003 </font>{
<font color="#555555">004 </font> PreparedStatement pstmt = con.prepareStatement(
<font color="#555555">005 </font> <font color="#0000FF">"SELECT count(*) FROM ?"</font>
<font color="#555555">006 </font> );
<font color="#555555">007 </font> String[] aTables = {<font color="#0000FF">"dir"</font>, <font color="#0000FF">"file"</font>};
<font color="#555555">008 </font> <font color="#0000AA">for</font> (<font color="#006699">int</font> i = 0; i < aTables.length; ++i) {
<font color="#555555">009 </font> pstmt.setString(1, aTables[i]);
<font color="#555555">010 </font> ResultSet rs = pstmt.executeQuery();
<font color="#555555">011 </font> <font color="#0000AA">if</font> (!rs.next()) {
<font color="#555555">012 </font> <font color="#0000AA">throw</font> <font color="#0000AA">new</font> SQLException(<font color="#0000FF">"SELECT COUNT(*): no result"</font>);
<font color="#555555">013 </font> }
<font color="#555555">014 </font> System.out.println(aTables[i] + <font color="#0000FF">": "</font> + rs.getInt(1));
<font color="#555555">015 </font> }
<font color="#555555">016 </font> pstmt.close();
<font color="#555555">017 </font>}</pre>
</font>
</td>
</tr>
</table>
<i>
Listing 42.12: Verwenden eines PreparedStatement</i></p>
<p>
Das <a href="index_p.html#ixb102304"><font color=#000080><tt>PreparedStatement</tt></font></a>
enthält hier den Namen der Tabelle als Parameter. In einer Schleife
nehmen wir nun für die Tabellen »dir« und »file«
jeweils eine Parametrisierung vor und führen dann die eigentliche
Abfrage durch. Der Rückgabewert von <a href="index_e.html#ixb102249"><font color=#000080><tt>executeQuery</tt></font></a>
entspricht dem der Basisklasse, so dass der obige Code sich prinzipiell
nicht von dem in <a href="k100268.html#zaehlenverzdateien">Abschnitt 42.3.5</a>
unterscheidet.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=1></td>
<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>
<p>
Nicht alle Datenbanken erlauben es, <i>Tabellennamen</i> zu parametrisieren,
sondern beschränken diese Fähigkeit auf Argumente von Such-
oder Änderungsausdrücken. Tatsächlich läuft unser
Beispiel zwar mit InstantDB, aber beispielsweise nicht mit MS Access
95.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#CC0000">
<tr>
<td><font color="#FFFFFF"> Warnung </font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
</tr>
</table>
<!-- Section -->
<a name="sectlevel3id042004007"></a>
<h3>42.4.7 SQL-Kurzreferenz </h3>
<p>
Dieser Abschnitt gibt eine kurze Übersicht der gebräuchlichsten
SQL-Anweisungen in ihren grundlegenden Ausprägungen. Er ersetzt
weder ein Tutorial noch eine Referenz und ist zu keinem der bekannten
SQL-Standards vollständig kompatibel. Trotzdem mag er für
einfache Experimente nützlich sein und helfen, die ersten JDBC-Anbindungen
zum Laufen zu bringen. Für »ernsthafte« Datenbankanwendungen
sollte zusätzliche Literatur konsultiert und dabei insbesondere
auf die Spezialitäten der verwendeten Datenbank geachtet werden.
<p>
Die nachfolgenden Syntaxbeschreibungen sind an die bei SQL-Anweisungen
übliche Backus-Naur-Form angelehnt:
<ul>
<li>Terminalsymbole (Schlüsselwörter) sind großgeschrieben.
<li>Weitere Terminalsymbole sind die runden Klammern, das Komma und
die in den Suchausdrücken verwendeten Operatoren.
<li>Nichtterminalsymbole sind kursiv geschrieben.
<li>Optionale Teile stehen in eckigen Klammern.
<li>Der senkrechte Strich trennt Alternativen. Stehen sie in eckigen
Klammern, können sie auch ganz weggelassen werden. Stehen sie
in geschweiften Klammern, muss genau eine der Alternativen verwendet
werden.
<li>Drei Punkte zeigen an, dass die davorstehende Anweisungsfolge
wiederholt werden kann.
</ul>
<!-- Section -->
<a name="sectlevel4id042004007001"></a>
<h4>Ändern von Datenstrukturen </h4>
<p>
Mit <a name="ixa103132"><a href="index_c.html#ixb102306"><font color=#000080><tt>CREATE TABLE</tt></font></a></a>
kann eine neue Tabelle angelegt werden. Mit <a name="ixa103133"><a href="index_d.html#ixb102307"><font color=#000080><tt>DROP TABLE</tt></font></a></a>
kann sie gelöscht und mit <a name="ixa103134"><a href="index_a.html#ixb102308"><font color=#000080><tt>ALTER TABLE</tt></font></a></a>
ihre Struktur geändert werden. Mit <a name="ixa103135"><a href="index_c.html#ixb102309"><font color=#000080><tt>CREATE INDEX</tt></font></a></a>
kann ein neuer Index angelegt, mit <a name="ixa103136"><a href="index_d.html#ixb102310"><font color=#000080><tt>DROP INDEX</tt></font></a></a>
wieder gelöscht werden.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
CREATE TABLE <i>TabName</i>
(<i>ColName</i> <i>DataType</i> [DEFAULT <i>ConstExpr</i>]
[<i>ColName</i> <i>DataType</i> [DEFAULT <i>ConstExpr</i>]]...)
ALTER TABLE <i>TabName</i>
ADD (<i>ColName</i> <i>DataType</i>
[<i>ColName</i> <i>DataType</i>]...)
CREATE [UNIQUE] INDEX <i>IndexName</i>
ON <i>TabName</i>
(<i>ColName</i> [ASC|DESC]
[, <i>ColName</i> [ASC|DESC]]...)
DROP TABLE <i>TabName</i>
DROP INDEX <i>IndexName</i>
</pre>
</font>
</td>
</tr>
</table>
<p>
<i>TabName</i>, <i>ColName</i> und <i>IndexName</i> sind SQL-Bezeichner.
<i>ConstExpr</i> ist ein konstanter Ausdruck, der einen Standardwert
für eine Spalte vorgibt. <i>DataType</i> gibt den Datentyp der
Spalte an, die gebräuchlichsten von ihnen können <a href="k100269.html#sqldatentypen">Tabelle 42.4</a>
entnommen werden. <a name="sqldatentypen"></a>
<p>
<table cols=2 border width=66%>
<tr>
<td valign=top align=left width=33%><b>Bezeichnung </b></td>
<td valign=top align=left width=66%><b>Bedeutung</b></td></tr>
<tr>
<td valign=top align=left>CHAR(n) </td>
<td valign=top align=left>Zeichenkette der (festen) Länge <i>n</i>.</td></tr>
<tr>
<td valign=top align=left>VARCHAR(n) </td>
<td valign=top align=left>Zeichenkette variabler Länge mit max.
<i>n</i> Zeichen.</td></tr>
<tr>
<td valign=top align=left>SMALLINT </td>
<td valign=top align=left>16-Bit-Ganzzahl mit Vorzeichen.</td></tr>
<tr>
<td valign=top align=left>INTEGER </td>
<td valign=top align=left>32-Bit-Ganzzahl mit Vorzeichen.</td></tr>
<tr>
<td valign=top align=left>REAL </td>
<td valign=top align=left>Fließkommazahl mit etwa 7 signifikanten
Stellen.</td></tr>
<tr>
<td valign=top align=left>FLOAT </td>
<td valign=top align=left>Fließkommazahl mit etwa 15 signifikanten
Stellen. Auch als DOUBLE oder DOUBLE PRECISION bezeichnet.</td></tr>
<tr>
<td valign=top align=left>DECIMAL(n,m) </td>
<td valign=top align=left>Festkommazahl mit <i>n</i> Stellen, davon
<i>m</i> Nachkommastellen. Ähnlich NUMERIC.</td></tr>
<tr>
<td valign=top align=left>DATE </td>
<td valign=top align=left>Datum (evtl. mit Uhrzeit). Verwandte Typen
sind TIME und TIMESTAMP.</td></tr>
</table>
<p><i>
Tabelle 42.4: SQL-Datentypen</i></p>
<!-- Section -->
<a name="sectlevel4id042004007002"></a>
<h4>Ändern von Daten </h4>
<p>
Ein neuer Datensatz kann mit <a name="ixa103137"><a href="index_i.html#ixb102267"><font color=#000080><tt>INSERT INTO</tt></font></a></a>
angelegt werden. Soll ein bestehender Datensatz geändert werden,
ist dazu <a name="ixa103138"><a href="index_u.html#ixb102268"><font color=#000080><tt>UPDATE</tt></font></a></a>
zu verwenden. Mit <a name="ixa103139"><a href="index_d.html#ixb102269"><font color=#000080><tt>DELETE FROM</tt></font></a></a>
kann er gelöscht werden.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
INSERT INTO <i>TabName</i>
[( <i>ColName</i> [,<i>ColName</i>] )]
VALUES (<i>Expr</i> [,<i>Expr</i>]...)
UPDATE <i>TabName</i>
SET <i>ColName</i> = {<i>Expr</i>|NULL}
[,<i>ColName</i> = {<i>Expr</i>|NULL}]...
[WHERE <i>SearchCond</i>]
DELETE FROM <i>TabName</i>
[WHERE <i>SearchCond</i>]
</pre>
</font>
</td>
</tr>
</table>
<p>
<i>TabName</i> und <i>ColName</i> sind die Bezeichner der gewünschten
Tabelle bzw. Spalte. <i>Expr</i> kann eine literale Konstante oder
ein passender Ausdruck sein. <i>SearchCond</i> ist eine Suchbedingung,
mit der angegeben wird, auf welche Sätze die <a href="index_u.html#ixb102268"><font color=#000080><tt>UPDATE</tt></font></a>-
oder <a href="index_d.html#ixb102269"><font color=#000080><tt>DELETE FROM</tt></font></a>-Anweisung
angewendet werden soll. Wird sie ausgelassen, wirken die Änderungen
auf alle Sätze. Wir kommen im nächsten Abschnitt auf die
Syntax der Suchbedingung zurück. Wird bei der <a href="index_i.html#ixb102267"><font color=#000080><tt>INSERT INTO</tt></font></a>-Anweisung
die optionale Feldliste ausgelassen, müssen Ausdrücke für
<i>alle</i> Felder angegeben werden.
<!-- Section -->
<a name="sectlevel4id042004007003"></a>
<h4>Lesen von Daten </h4>
<p>
Das Lesen von Daten erfolgt mit der <a name="ixa103140"><a href="index_s.html#ixb102311"><font color=#000080><tt>SELECT</tt></font></a></a>-Anweisung.
Ihre festen Bestandteile sind die Liste der Spalten <i>ColList</i>
und die Liste der Tabellen, die in der Abfrage verwendet werden sollen.
Daneben gibt es eine Reihe von optionalen Bestandteilen:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
SELECT [ALL|DISTINCT] <i>ColList</i>
FROM <i>TabName</i> [,<i>TabName</i>]...
[WHERE <i>SearchCond</i>]
[GROUP BY <i>ColName</i> [,<i>ColName</i>]...]
[HAVING <i>SearchCond</i>]
[UNION <i>SubQuery</i>]
[ORDER BY <i>ColName</i> [ASC|DESC]
[,<i>ColName</i> [ASC|DESC]]...]
</pre>
</font>
</td>
</tr>
</table>
<p>
Die Spaltenliste kann entweder einzelne Felder aufzählen, oder
es können durch Angabe eines Sternchens »*« alle Spalten
angegeben werden. Wurde mehr als eine Tabelle angegeben und sind die
Spaltennamen nicht eindeutig, kann ein Spaltenname durch Voranstellen
des Tabellennamens und eines Punkts qualifiziert werden. Zusätzlich
können die Spaltennamen mit dem Schlüsselwort »AS«
ein (möglicherweise handlicheres) Synonym erhalten. Die Syntax
von <i>ColList</i> ist:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
<i>ColExpr</i> [AS <i>ResultName</i>]
[,<i>ColExpr</i> AS <i>ResultName</i>]]...
</pre>
</font>
</td>
</tr>
</table>
<p>
Zusätzlich gibt es einige numerische Aggregatfunktionen, mit
denen der Wert der als Argument angegebenen Spalte über alle
Sätze der Ergebnismenge kumuliert werden kann: <a name="tableid042005"></a>
<p>
<table cols=2 border width=66%>
<tr>
<td valign=top align=left width=33%><b>Bezeichnung</b></td>
<td valign=top align=left width=66%><b>Bedeutung</b></td></tr>
<tr>
<td valign=top align=left>COUNT </td>
<td valign=top align=left>Anzahl der Sätze</td></tr>
<tr>
<td valign=top align=left>AVG </td>
<td valign=top align=left>Durchschnitt</td></tr>
<tr>
<td valign=top align=left>SUM </td>
<td valign=top align=left>Summe</td></tr>
<tr>
<td valign=top align=left>MIN </td>
<td valign=top align=left>Kleinster Wert</td></tr>
<tr>
<td valign=top align=left>MAX </td>
<td valign=top align=left>Größter Wert</td></tr>
</table>
<p><i>
Tabelle 42.5: SQL-Aggregatfunktionen</i></p>
<p>
Die <a name="ixa103141"><a href="index_w.html#ixb102312"><font color=#000080><tt>WHERE</tt></font></a></a>-Klausel
definiert die Suchbedingung. Wurde sie nicht angegeben, liefert die
Anweisung alle vorhandenen Sätze. Der Suchausdruck <i>SearchCond</i>
kann sehr unterschiedliche Formen annehmen. Zunächst kann eine
Spalte mit Hilfe der relationalen Operatoren <, <=, >, >=,
= und <> mit einer anderen Spalte oder einem Ausdruck verglichen
werden. Die Teilausdrücke können mit den logischen Operatoren
<a name="ixa103142"><a href="index_a.html#ixb102313"><font color=#000080><tt>AND</tt></font></a></a>,
<a name="ixa103143"><a href="index_o.html#ixb102314"><font color=#000080><tt>OR</tt></font></a></a>
und <a name="ixa103144"><a href="index_n.html#ixb102315"><font color=#000080><tt>NOT</tt></font></a></a>
verknüpft werden, die Auswertungsreihenfolge kann in der üblichen
Weise durch Klammerung gesteuert werden.
<p>
Mit Hilfe des Schlüsselworts <a name="ixa103145"><a href="index_l.html#ixb102316"><font color=#000080><tt>LIKE</tt></font></a></a>
kann eine Ähnlichkeitssuche durchgeführt werden:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
<i>Expr</i> LIKE <i>Pattern</i>
</pre>
</font>
</td>
</tr>
</table>
<p>
Mit Hilfe der Wildcards »%« und »_« können
auch unscharf definierte Begriffe gesucht werden. Jedes Vorkommen
von »%« passt auf eine beliebige Anzahl beliebiger Zeichen,
jedes »_« steht für genau ein beliebiges Zeichen. Manche
Datenbanken unterscheiden zwischen Groß- und Kleinschreibung,
andere nicht.
<p>
Mit Hilfe der Klauseln <a name="ixa103146"><a href="index_i.html#ixb102317"><font color=#000080><tt>IS NULL</tt></font></a></a>
und <a name="ixa103147"><a href="index_i.html#ixb102318"><font color=#000080><tt>IS NOT NULL</tt></font></a></a>
kann getestet werden, ob der Inhalt einer Spalte den Wert NULL enthält
oder nicht:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
<i>ColName</i> IS [NOT] NULL
</pre>
</font>
</td>
</tr>
</table>
<p>
Mit dem <a name="ixa103148"><a href="index_b.html#ixb102319"><font color=#000080><tt>BETWEEN</tt></font></a></a>-Operator
kann bequem festgestellt werden, ob ein Ausdruck innerhalb eines vorgegebenen
Wertebereichs liegt oder nicht:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
<i>Expr</i> BETWEEN <i>Expr</i> AND <i>Expr</i>
</pre>
</font>
</td>
</tr>
</table>
<p>
Neben den einfachen Abfragen gibt es eine Reihe von Abfragen, die
mit <a name="ixa103149"><i>Subqueries</i></a> (Unterabfragen) arbeiten:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
EXISTS (<i>SubQuery</i>)
<i>Expr</i> [NOT] IN (<i>SubQuery</i>)
<i>Expr</i> <i>RelOp</i> {ALL|ANY} (<i>SubQuery</i>)
</pre>
</font>
</td>
</tr>
</table>
<p>
Die Syntax von <i>SubQuery</i> entspricht der einer normalen <a href="index_s.html#ixb102311"><font color=#000080><tt>SELECT</tt></font></a>-Anweisung.
Sie definiert eine separat definierte Menge von Daten, die als Teilausdruck
in einer Suchbedingung angegeben wird. Der <a name="ixa103150"><a href="index_e.html#ixb102321"><font color=#000080><tt>EXISTS</tt></font></a></a>-Operator
testet, ob die Unterabfrage mindestens ein Element enthält. Mit
dem <a name="ixa103151"><a href="index_i.html#ixb102322"><font color=#000080><tt>IN</tt></font></a></a>-Operator
wird getestet, ob der angegebene Ausdruck in der Ergebnismenge enthalten
ist. Die Ergebnismenge kann auch literal als komma-separierte Liste
von Werten angegeben werden. Schließlich kann durch Angabe eines
relationalen Operators getestet werden, ob der Ausdruck zu mindestens
einem (<a name="ixa103152"><a href="index_a.html#ixb102323"><font color=#000080><tt>ANY</tt></font></a></a>)
oder allen (<a name="ixa103153"><a href="index_a.html#ixb102324"><font color=#000080><tt>ALL</tt></font></a></a>)
Sätzen der Unterabfrage in der angegebenen Beziehung steht. Bei
den beiden letzten Unterabfragen sollte jeweils nur eine einzige Spalte
angegeben werden.
<p>
Die <a name="ixa103154"><a href="index_g.html#ixb102325"><font color=#000080><tt>GROUP BY</tt></font></a></a>-Klausel
dient dazu, die Sätze der Ergebnismenge zu Gruppen zusammenzufassen,
bei denen die Werte der angegebenen Spalten gleich sind. Sie wird
typischerweise zusammen mit den oben erwähnten Aggregatfunktionen
verwendet. Mit <a name="ixa103155"><a href="index_h.html#ixb102326"><font color=#000080><tt>HAVING</tt></font></a></a>
kann zusätzlich eine Bedingung angegeben werden, mit der die
gruppierten Ergebnissätze »nachgefiltert« werden.
<p>
Mit dem <a name="ixa103156"><a href="index_u.html#ixb102327"><font color=#000080><tt>UNION</tt></font></a></a>-Operator
können die Ergebnismengen zweier <a href="index_s.html#ixb102311"><font color=#000080><tt>SELECT</tt></font></a>-Anweisungen
zusammengefasst werden. Das wird typischerweise gemacht, wenn die
gesuchten Ergebnissätze aus mehr als einer Tabelle stammen (andernfalls
könnte der <a href="index_o.html#ixb102314"><font color=#000080><tt>OR</tt></font></a>-Operator
verwendet werden).
<p>
Die <a name="ixa103157"><a href="index_o.html#ixb102328"><font color=#000080><tt>ORDER BY</tt></font></a></a>-Klausel
kann angegeben werden, um die Reihenfolge der Sätze in der Ergebnismenge
festzulegen. Die Sätze werden zunächst nach der ersten angegebenen
Spalte sortiert, bei Wertegleichheit nach der zweiten, der dritten
usw. Mit Hilfe der Schlüsselwörter <a name="ixa103158"><a href="index_a.html#ixb102329"><font color=#000080><tt>ASC</tt></font></a></a>
und <a name="ixa103159"><a href="index_d.html#ixb102330"><font color=#000080><tt>DESC</tt></font></a></a>
kann angegeben werden, ob die Werte auf- oder absteigend sortiert
werden sollen.
<hr>
<table border=0 cellpadding=0 cellspacing=1 width="100%">
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
<td align="right">Handbuch der Java-Programmierung, 5. Auflage, Addison
Wesley, Version 5.0.1
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100265.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100268.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100270.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100271.html"> >> </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
<td align="right">© 1998, 2007 Guido Krüger & Thomas
Stark, <a href="http://www.javabuch.de">http://www.javabuch.de</a>
</table>
<a name="endofbody"></a>
</body>
</html>
|