Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Über den Autor
Vorwort zur 4. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Klassendesign und Vererbung
4 Weitere .NET-Datentypen
5 Weitere Möglichkeiten von C#
6 Projektmanagement und Visual Studio 2008
7 Fehlerbehandlung und Debugging
8 LINQ
9 Multithreading und asynchrone Methodenaufrufe
10 Arbeiten mit Dateien und Streams
11 Serialisierung
12 Einige wichtige .NET-Klassen
13 Grundlagen zum Erstellen einer Windows-Anwendung
14 Die wichtigsten Steuerelemente
15 Tastatur- und Mausereignisse
16 MDI-Anwendungen
17 Grafische Programmierung mit GDI+
18 Das Drucken (Printing)
19 Steuerelemente entwickeln
20 Programmiertechniken
21 WPF – die Grundlagen
22 Die Layoutcontainer
23 Die WPF-Controls
24 Konzepte von WPF
25 ADO.NET – die Verbindung zu einer Datenbank herstellen
26 Die Datenbankabfrage
27 Der SqlDataAdapter
28 Daten im lokalen Speicher – das DataSet
29 Eine Datenbank aktualisieren
30 Stark typisierte DataSets
31 Weitergabe von Anwendungen
Stichwort

Download:
- ZIP, ca. 13,6 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual C# 2008 von Andreas Kuehnel
Das umfassende Handbuch
Buch: Visual C# 2008

Visual C# 2008
geb., mit DVD
1.366 S., 49,90 Euro
Galileo Computing
ISBN 978-3-8362-1172-7
Pfeil 26 Die Datenbankabfrage
Pfeil 26.1 Das »SqlCommand«-Objekt
Pfeil 26.1.1 Ein »SqlCommand«-Objekt erzeugen
Pfeil 26.1.2 Ausführen des »SqlCommand«-Objekts
Pfeil 26.1.3 Die Eigenschaft »CommandTimeout« des »SqlCommand«-Objekts
Pfeil 26.1.4 Aktionsabfragen absetzen
Pfeil 26.1.5 Abfragen, die genau ein Ergebnis liefern
Pfeil 26.2 Das »SqlDataReader«-Objekt
Pfeil 26.2.1 Datensätze einlesen
Pfeil 26.2.2 Schließen des »SqlDataReader«-Objekts
Pfeil 26.2.3 MARS (Multiple Active Resultsets)
Pfeil 26.2.4 Batch-Abfragen mit »NextResult« durchlaufen
Pfeil 26.2.5 Das Schema eines »SqlDataReader«-Objekts untersuchen
Pfeil 26.3 Parametrisierte Abfragen
Pfeil 26.3.1 Parametrisierte Abfragen mit dem SqlClient-Datenprovider
Pfeil 26.3.2 Die Klasse »SqlParameter«
Pfeil 26.3.3 Parametrisierte Abfragen mit dem OleDb-Datenprovider
Pfeil 26.4 Asynchrone Abfragen
Pfeil 26.4.1 Das Polling-Verfahren
Pfeil 26.4.2 Bereitstellen einer Rückrufmethode
Pfeil 26.5 Gespeicherte Prozeduren (Stored Procedures)
Pfeil 26.5.1 Allgemeines zu gespeicherten Prozeduren
Pfeil 26.5.2 Gespeicherte Prozeduren im Visual Studio 2008 erstellen
Pfeil 26.5.3 Eine gespeicherte Prozedur aufrufen
Pfeil 26.5.4 Komplexe gespeicherte Prozeduren

26 Die Datenbankabfrage

Grundlage einer Datenbankabfrage ist die Verbindung zu der Datenquelle. Wie Sie das SqlConnection-Objekt dazu erzeugen, hat das letzte Kapitel gezeigt. Nun gehen wir den nächsten Schritt und wollen uns damit beschäftigen, wie Daten aus der Datenbank abgerufen werden. Damit wird auch in einem Zug erklärt, wie Daten in der Originaldatenbank verändert, hinzugefügt und gelöscht werden. Für solche Operationen stellt ADO.NET eine weitere Klasse zur Verfügung, die je nach eingesetztem Datenprovider SqlCommand, OleDbCommand oder OdbcCommand heißt. Command-Objekte gehören zur Gruppe derjenigen Objekte, die auf die Verbindung zum Datenbankserver angewiesen sind.

Neben der Klasse SqlCommand werden Sie weitere wichtige Klassen kennenlernen, allen voran die Klasse SqlDataReader, die die Datensätze einer Ergebnisliste durchläuft oder Schemainformationen einer Tabelle abruft. SqlDataReader ist tatsächlich in der gesamten ADO.NET-Klassenbibliothek das einzige Objekt, das Dateninformationen abrufen kann. Auch wenn wir uns später mit der Klasse SqlDataAdapter beschäftigen, die über die Methode Fill ein DataSet zu füllen vermag, hält der DataReader im Hintergrund die Fäden in der Hand. Von außen betrachtet, können wir das allerdings nicht direkt erkennen. Am Ende des ADO.NET-Teils dieses Buches werden Sie noch einmal dem SqlCommand-Objekt begegnen, wenn wir abweichend von der Standardvorgabe unsere eigene Aktualisierungslogik codieren.


Galileo Computing - Zum Seitenanfang

26.1 Das »SqlCommand«-Objekt Zur nächsten ÜberschriftZur vorigen Überschrift

Das SqlCommand-Objekt repräsentiert einen SQL-Befehl oder eine gespeicherte Prozedur. In der Eigenschaft CommandText wird die SQL-Anweisung bzw. die gespeicherte Prozedur festgelegt. Die Ausführung wird mit einer der Execute-Methoden gestartet.

Als kleinen Vorgeschmack möchte ich Ihnen ein Beispiel zeigen. Darin wird die Verbindung zu der Beispieldatenbank Northwind des SQL Servers aufgebaut. In der Tabelle Products, in der alle Artikel geführt sind, ist unter anderem ein Artikel mit der Bezeichnung Chai (Spalte ProductName) gespeichert. Angenommen, dieser sei falsch und soll nun in Sojasauce geändert werden. Dazu übergeben wir der Eigenschaft CommandText des SqlCommand-Objekts ein entsprechendes UPDATE-Kommando und führen es mit ExecuteNonQuery aus.

// ---------------------------------------------------
// Beispiel: ...\Kapitel 26\ExecuteNonQueryDemo
// -------------------------------------------------------
class Program {

  static void Main(string[] args) { 
    SqlConnection con = new SqlConnection("..."); 
    SqlCommand cmd = new SqlCommand(); 
    cmd.CommandText = "UPDATE Products " + 
                      "SET ProductName='Sojasauce' " + 
                      "WHERE ProductName='Chai'"; 
    cmd.Connection = con; 
    con.Open(); 
    cmd.ExecuteNonQuery(); 
    con.Close(); 
  } 
}

Vom Erfolg der Operation können Sie sich auf verschiedene Weisen überzeugen. Sie könnten sich einerseits mit dem Tool SQL Server Management Studio von SQL Server 2005 den Inhalt der nun geänderten Tabelle anzeigen lassen. Sie können das aber auch aus dem Server-Explorer des Visual Studio 2008 heraus, den Sie über das Menü Ansicht öffnen. Fügen Sie über das Kontextmenü des Knotens Datenverbindungen die Verbindung zu der Datenbank Northwind hinzu. Ein Assistent, den wir uns später noch genauer ansehen werden, führt Sie durch den gesamten Verbindungsprozess, an dessen Ende Sie die Möglichkeit haben, sich den aktuellen Inhalt der Tabelle Products in Visual Studio 2005 anzeigen zu lassen.


Galileo Computing - Zum Seitenanfang

26.1.1 Ein »SqlCommand«-Objekt erzeugen Zur nächsten ÜberschriftZur vorigen Überschrift

Um ein Kommando gegen eine Datenbank abzusetzen, wird ein SqlCommand-Objekt benötigt. Es spielt dabei keine Rolle, ob es sich um eine Auswahlabfrage (SELECT) oder Aktionsabfrage (INSERT, UPDATE oder DELETE) handelt. Das SQL-Kommando wird der Eigenschaft CommandText des SqlCommand-Objekts zugewiesen. Das ist aber noch nicht ausreichend, denn zusätzlich zum Befehl muss das SqlCommand-Objekt auch den Datenbankserver und die Datenbank kennen. Das heißt nichts anderes, als dass das SqlCommand-Objekt wissen muss, welches SqlConnection-Objekt die Verbindung zur Datenbank beschreibt.

Um diese Anforderungen zu erfüllen, stehen Ihnen mehrere Konstruktoren zur Verfügung. Sie können, wie im Beispiel zuvor gezeigt, den parameterlosen Konstruktor bemühen, müssen dann aber der Eigenschaft SqlConnection des SqlCommand-Objekts die Referenz auf SqlConnection mitteilen. Einer anderen Konstruktorüberladung können Sie neben der Referenz auf das SqlConnection-Objekt auch das abzusetzende Kommando als Zeichenfolge übergeben.

SqlCommand cmd = new SqlCommand("UPDATE Products " + 
   "SET ProductName='Sojasauce' WHERE ProductName='Chai'");

Die Methode »CreateCommand« des Connection-Objekts

Es gibt noch eine zweite Variante, sich eine Referenz auf ein SqlCommand-Objekt zu besorgen. Dazu wird die Methode CreateCommand auf dem Sqlonnection-Objekt aufgerufen, die als Rückgabewert das provider-spezifische SqlCommand-Objekt liefert.

SqlConnection con = new SqlConnection("..."); 
SqlCommand cmd = con.CreateCommand();

Galileo Computing - Zum Seitenanfang

26.1.2 Ausführen des »SqlCommand«-Objekts Zur nächsten ÜberschriftZur vorigen Überschrift

Die CommandText-Eigenschaft legt das Kommando fest, das ausgeführt werden soll. Es kann sich dabei um ein SQL-Kommando oder eine gespeicherte Prozedur handeln. Bei den SQL-Kommandos werden zwei Kategorien unterschieden:

  • Auswahlabfragen
  • Aktionsabfragen

Eine Auswahlabfrage basiert auf dem SELECT-Statement und liefert immer ein Ergebnis zurück. Dazu gehören auch die Abfragen, die eine Aggregatfunktion wie SUM oder COUNT aufrufen und nur einen Ergebniswert liefern. Eine typische Auswahlabfrage wäre zum Beispiel:

SELECT ProductName, UnitPrice FROM Products WHERE UnitPrice < 100

Das Resultat dieser Abfrage bilden alle Datensätze der Tabelle Northwind, die diejenigen Produkte beschreiben, deren Preis kleiner 100 ist.

Eine Aktionsabfrage manipuliert die Datenbank. Dabei kann es sich

  • um die Aktualisierung der Daten (DML-Abfrage = Data Manipulation Language-Abfrage) oder
  • um die Änderung der Datenbankstruktur (DDL-Abfrage = Data Definition Language-Abfrage)

handeln. Mit

UPDATE Products 
SET ProductName='Sojasauce' 
WHERE ProductName='Chai'

hatten wir eingangs eine DML-Abfrage abgesetzt, die zwar einen Datensatz in Products änderte, selbst aber keine Ergebnismenge lieferte.

Wie Sie sehen, führt das Absetzen eines Befehls zu ganz unterschiedlichen Reaktionen des Datenbankservers. Das SqlCommand-Objekt trägt dem Rechnung und stellt mit

  • ExecuteNonQuery
  • ExecuteReader
  • ExecuteScalar
  • ExecuteXmlReader

vier Methoden zur Verfügung, die speziell auf die einzelnen Abfragen abgestimmt sind und synchron ausgeführt werden. Synchron bedeutet, dass die Clientanwendung nach dem Methodenaufruf so lange wartet, bis das Ergebnis der Frage vom Datenbankserver eintrifft. Gegebenenfalls kann das eine längere Zeitspanne beanspruchen. Sie können aber Datenbankabfragen auch asynchron ausführen. Der Client muss dann nicht warten, bis die Abfrageausführung beendet ist, sondern kann weiterarbeiten, bis ihm signalisiert wird, dass die Ergebnisse vollständig vorliegen. Entsprechende asynchrone Methoden werden vom Command-Objekt bereitgestellt.


Galileo Computing - Zum Seitenanfang

26.1.3 Die Eigenschaft »CommandTimeout« des »SqlCommand«-Objekts Zur nächsten ÜberschriftZur vorigen Überschrift

Wird eine Abfrage mit ExcuteScalar, EcexuteNonQuery oder ExcuteReader ausgeführt, wartet das SqlCommand-Objekt per Vorgabe 30 Sekunden auf das Eintreffen der ersten Abfrageergebnisse. Das Überschreiten der eingestellten Zeit hat zur Folge, dass eine Ausnahme ausgelöst wird.

Mit der Eigenschaft CommandTimeout kann die Voreinstellung verändert werden. Mit der Einstellung »0« wartet das SqlCommand-Objekt eine unbegrenzte Zeit. Empfehlenswert ist das allerdings nicht. Eine Abfrage, die gerade ausgeführt wird, könnte durchaus so lange andauern, dass die voreingestellte Zeit überschritten wird. In diesem Fall hat das keine weiteren Auswirkungen, weil eine laufende Abfrage nicht unterbrochen wird.


Galileo Computing - Zum Seitenanfang

26.1.4 Aktionsabfragen absetzen Zur nächsten ÜberschriftZur vorigen Überschrift

Abfragen, die Änderungen an den Originaldaten der Datenbank nach sich ziehen (UPDATE, DELETE, INSERT) oder die Struktur einer Datenbank verändern (z. B. CREATE TABLE), werden mit der Methode ExecuteNonQuery abgesetzt.

public int ExecuteNonQuery();

Handelt es sich bei dem Befehl um ein UPDATE-, INSERT- oder DELETE-Kommando, können Sie über den Rückgabewert die Anzahl der von der Anweisung betroffenen Datenzeilen feststellen.

Datensätze hinzufügen

Im folgenden Beispielprogramm wird der Tabelle Products ein Datensatz hinzugefügt. Dabei wird der parametrisierte Konstruktor der Klasse SqlCommand verwendet, der im ersten Parameter den SQL-Befehl und im zweiten die Referenz auf das SqlConnection-Objekt entgegennimmt.

// ---------------------------------------------------
// Beispiel: ...\Kapitel 26\DatensatzHinzufügen
// -------------------------------------------------------
class Program {

  static void Main(string[] args) { 
    SqlConnection con = new SqlConnection("..."); 
    // SQL-Befehl 
    string strSQL = 
       "INSERT INTO Products(ProductName, Discontinued) " + 
       "VALUES('Schweizer Käse',0)"; 
    try { 
      con.Open(); 
      SqlCommand cmd = new SqlCommand(strSQL, con); 
      // Kommando absetzen 
      cmd.ExecuteNonQuery(); 
    } 
    catch (Exception e) { 
      Console.WriteLine("Fehlermeldung: {0}", e.Message); 
    } 
    con.Close(); 
  } 
}

Datensätze löschen

Der Datensatz aus dem vorhergehenden Beispiel soll nun wieder gelöscht werden. Da wir nun daran interessiert sind, ob und wie viele Datenzeilen von einer Löschanweisung betroffen sind, werten wir den Rückgabewert der Methode ExecuteNonQuery an der Konsole aus.

// ---------------------------------------------------
// Beispiel: ...\Kapitel 26\DatensatzLöschen
// -------------------------------------------------------
class Program {

  static void Main(string[] args) { 
    SqlConnection con = new SqlConnection("..."); 
    try { 
      con.Open(); 
      string strSQL = "DELETE FROM Products " + 
                      "WHERE ProductName='Schweizer Käse'"; 
      SqlCommand cmd = new SqlCommand(strSQL, con); 
      Console.Write("Anzahl der gelöschten Datensätze = "); 
      Console.WriteLine(cmd.ExecuteNonQuery()); 
    } 
 
    catch (Exception e) { 
      Console.WriteLine("Fehlermeldung: {0}", e.Message); 
    } 
    con.Close(); 
    Console.ReadLine(); 
  } 
}

Nach dem ersten Start des Programms wird der im Abschnitt zuvor hinzugefügte Datensatz gelöscht. An der Konsole sehen wir das bestätigt, da die Zahl 1 ausgegeben wird. Rufen wir das Programm ein zweites Mal auf, wird kein Datensatz gefunden, der dem Kriterium ProductName='Schweizer Käse' entspricht. Das spiegelt sich in der Ausgabe

Die Anzahl der gelöschten Datensätze = 0

wider.

Datensätze ändern

Zu Beginn dieses Abschnitts wurde in dem Beispiel ExecuteNonQueryDemo bereits gezeigt, wie Sie Datensätze in der Datenbank editieren können. Daher soll an dieser Stelle auf ein weiteres Beispiel verzichtet werden.


Galileo Computing - Zum Seitenanfang

26.1.5 Abfragen, die genau ein Ergebnis liefern topZur vorigen Überschrift

Mit der SELECT-Anweisung können Sie eine Datensatzliste nach bestimmten Auswahlkriterien aus einer Datenbank abzurufen. Der Befehl SELECT wird aber auch dann benutzt, wenn eine Aggregatfunktion definiert werden soll. Aggregatfunktionen liefern ein Ergebnis zurück. Beispielsweise können Sie mit

SELECT COUNT(*) FROM Northwind

die Anzahl der Artikel in der Tabelle Products ermitteln und mit

SELECT COUNT(*) FROM Products WHERE CategoryID = 1

feststellen, wie viele Artikel zur Kategorie 1 gehören. Neben COUNT stehen noch weitere Aggregatfunktionen zur Verfügung: SUM, um die Summe eines numerischen Ausdrucks zu ermitteln, AVG, um einen Durchschnittswert zu bilden, sowie MIN und MAX, um aus einem gegebenen Ausdruck den Maximal- bzw. Minimalwert zu erhalten.

Um den Rückgabewert einer Aggregatfunktion entgegenzunehmen, rufen Sie die Methode ExecuteScalar auf das SqlCommand-Objekt auf. Der Typ der Rückgabe ist Object, daher muss das Ergebnis noch in den passenden Datentyp konvertiert werden.

string strSQL = "SELECT COUNT(*) FROM Products WHERE CategoryID=1"; 
SqlCommand cmd = new SqlCommand(strSQL, con); 
int anzahlDS = Convert.ToInt32(cmd.ExecuteScalar());


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2008






Visual C# 2008
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Coding for Fun






 Coding for Fun


Zum Katalog: Einstieg in Visual C# 2008






 Einstieg in
 Visual C# 2008


Zum Katalog: Videotraining - Visual C# 2008






 Videotraining -
 Visual C# 2008


Zum Katalog: Fortgeschrittene Programmierung mit Visual C# 2008






 Fortgeschrittene
 Programmierung mit
 Visual C# 2008


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Visual Basic 2008






 Visual Basic 2008


Zum Katalog: Einstieg in XML






 Einstieg in XML


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de