7. Zugriff auf die Datenbanken
7.1. Allgemeines
Es gibt zahlreiche Datenbanken für Windows-Plattformen. Um darauf zuzugreifen, nutzen die Anwendungen sogenannte Treiber (Drivers).
![]() |
In der obigen Abbildung verfügt der Treiber über zwei Schnittstellen:
- die Schnittstelle I1, die der Anwendung zur Verfügung steht
- die Schnittstelle I2 zur Datenbank
Um zu vermeiden, dass eine für eine Datenbank B1 geschriebene Anwendung bei einer Migration auf eine andere Datenbank B2 neu geschrieben werden muss, wurden Standardisierungsbemühungen an der Schnittstelle I1 unternommen. Bei der Verwendung von Datenbanken mit „normalisierten“ Treibern wird die Datenbank B1 mit einem Treiber P1 bereitgestellt, die Datenbank B2 mit einem Treiber P2, und die Schnittstelle I1 dieser beiden Treiber ist identisch. Daher muss die Anwendung nicht neu geschrieben werden. So kann man beispielsweise eine Datenbank ACCESS auf eine Datenbank MySQL migrieren, ohne die Anwendung zu ändern.
Es gibt zwei Arten von standardisierten Treibern:
- die Treiber ODBC (Open DataBase Connectivity)
- die Treiber OLE und DB (Object Linking and Embedding DataBase)
Die Treiber ODBC ermöglichen den Zugriff auf Datenbanken. Die Datenquellen für die Treiber OLE und DB sind vielfältiger: Datenbanken, E-Mail-Systeme, Verzeichnisse usw. Es gibt keine Einschränkungen. Jede Datenquelle kann Gegenstand eines Treibers OLE oder DB sein, wenn ein Hersteller dies beschließt. Der Nutzen ist offensichtlich groß: Man erhält einen einheitlichen Zugriff auf eine große Vielfalt an Daten.
Die Plattform .NET wird mit zwei Arten von Datenzugriffsklassen ausgeliefert:
- die Klassen SQL und Server.NET
- die Klassen OLE und Db.NET
Die ersten Klassen ermöglichen einen direkten Zugriff auf den Microsoft-Server SGBD SQL ohne zwischengeschalteten Treiber. Die zweiten Klassen ermöglichen den Zugriff auf die Datenquellen OLE DB.

Die Plattform .NET wird (Stand: Mai 2002) mit drei Treibern OLE, DB für jeweils: SQL Server, Oracle und Microsoft Jet (Access) ausgeliefert. Wenn man mit einer Datenbank arbeiten möchte, für die ein Treiber ODBC, aber kein Treiber OLE oder DB vorhanden ist, ist dies nicht möglich. So kann man nicht mit SGBD und MySQL arbeiten, da diese (Stand Mai 2002) keine Treiber OLE und DB bereitstellen. Es gibt jedoch eine Reihe von Klassen, die den Zugriff auf die Datenquellen ermöglichen: die ODBC- und odbc.net-Klassen. Diese sind nicht standardmäßig im Lieferumfang des SDK enthalten und müssen von der Microsoft-Website heruntergeladen werden. In den folgenden Beispielen werden wir vor allem diese Klassen verwenden, da die meisten Datenbanken unter Windows mit einem solchen Treiber ausgeliefert werden. Hier ist beispielsweise eine Liste der auf einem Win 2000-Rechner installierten Treiber ODBC (Startmenü/Einstellungen/Systemsteuerung/Verwaltung):

Wählen Sie das Symbol „Datenquelle“ ODBC aus:

7.2. Die beiden Betriebsmodi einer Datenquelle
Die Plattform .NET ermöglicht die Nutzung einer Datenquelle auf zwei verschiedene Arten:
- Online-Modus
- Offline-Modus
Im Online-Modus
- eine Verbindung zur Datenquelle
- arbeitet mit der Datenquelle im Lese-/Schreibmodus
- schließt die Verbindung
Im Offline-Modus führt die Anwendung folgende Schritte aus:
- eine Verbindung zur Datenquelle auf
- ruft eine Speicherkopie aller oder eines Teils der Daten aus der Quelle ab
- schließt die Verbindung
- arbeitet mit der Speicherkopie der Daten im Lese-/Schreibmodus
- sobald die Arbeit abgeschlossen ist, eine Verbindung herstellt, die geänderten Daten an die Datenquelle sendet, damit diese sie berücksichtigt, und die Verbindung schließt
In beiden Fällen ist es die Verarbeitung und Aktualisierung der Daten, die Zeit in Anspruch nimmt. Stellen wir uns vor, diese Aktualisierungen würden von einem Benutzer vorgenommen, der Daten eingibt – dieser Vorgang kann Dutzende von Minuten dauern. Während dieser gesamten Zeit bleibt im verbundenen Modus die Verbindung zur Datenbank aufrechterhalten und die Änderungen werden sofort übernommen. Im nicht verbundenen Modus besteht während der Datenaktualisierung keine Verbindung zur Datenbank. Die Änderungen werden ausschließlich an der Speicherkopie vorgenommen. Sie werden erst nach Abschluss aller Vorgänge in einem Schritt an die Datenquelle übertragen.
Was sind die Vor- und Nachteile der beiden Methoden?
- Eine Verbindung beansprucht viele Systemressourcen. Bei vielen gleichzeitigen Verbindungen lässt sich im Offline-Modus deren Dauer auf ein Minimum reduzieren. Dies ist beispielsweise bei Webanwendungen mit Tausenden von Nutzern der Fall.
- Der Nachteil des Offline-Modus ist die schwierige Handhabung gleichzeitiger Aktualisierungen. Der Benutzer U1 ruft zum Zeitpunkt T1 Daten ab und beginnt, diese zu ändern. Zum Zeitpunkt T2 greift auch der Benutzer U2 auf die Datenquelle zu und erhält dieselben Daten. In der Zwischenzeit hat der Benutzer U1 bestimmte Daten geändert, diese jedoch noch nicht an die Datenquelle übertragen. U2 arbeitet daher mit Daten, von denen einige fehlerhaft sind. Die Klassen .NET bieten Lösungen zur Bewältigung dieses Problems, doch es ist nicht einfach zu lösen.
- Im verbundenen Modus stellt die gleichzeitige Aktualisierung von Daten durch mehrere Benutzer normalerweise kein Problem dar. Da die Verbindung zur Datenbank aufrechterhalten bleibt, verwaltet die Datenbank selbst diese gleichzeitigen Aktualisierungen. So sperrt Oracle eine Zeile in der Datenbank, sobald ein Benutzer sie ändert. Sie bleibt gesperrt und ist somit für andere Benutzer unzugänglich, bis derjenige, der sie geändert hat, seine Änderung bestätigt (Commit) oder rückgängig macht (Rollback).
- Wenn die Daten über das Netzwerk übertragen werden sollen, ist der Offline-Modus zu wählen. Er ermöglicht es, eine Momentaufnahme der Daten in einem Objekt namens „Dataset“ zu erhalten, das eine eigenständige Datenbank darstellt. Dieses Objekt kann über das Netzwerk zwischen Rechnern übertragen werden.
Wir befassen uns zunächst mit dem verbundenen Modus.
7.3. Datenzugriff im verbundenen Modus
7.3.1. Die Datenbanken des Beispiels
Wir betrachten eine Datenbank mit dem Namen ACCESS, die als articles.mdb bezeichnet wird und nur eine Tabelle namens ARTICLES mit folgender Struktur enthält:
name | Typ |
Code | 4-stelliger Artikelcode |
Name | Name (Zeichenkette) |
Preis | sein Preis (tatsächlicher Preis) |
stock_actuel | sein aktueller Lagerbestand (Ganzzahl) |
stock_minimum | der Mindestbestand (ganze Zahl), unterhalb dessen der Artikel nachbestellt werden muss |
Der Ausgangsinhalt lautet wie folgt:

Wir werden diese Grundlage sowohl anhand eines Testartikels ODBC als aucheinen Treiber OLE DB verwenden, um die Ähnlichkeit der beiden Ansätze aufzuzeigen und weil uns diese beiden Treiberarten für ACCESS zur Verfügung stehen.
Wir werden außerdem eine Datenbank MySQL DBARTICLES verwenden, die dieselbe einzige Tabelle ARTICLES enthält, denselben Inhalt und auf die über einen Treiber ODBC zugegriffen wird, um zu zeigen, dass die Anwendung, die für die Nutzung der Datenbank ACCESS geschrieben wurde, nicht geändert werden muss, um die Datenbank MySQL zu verwenden. Auf die Datenbank DBARTICLES kann ein Benutzer namens admarticles mit dem Passwort mdparticles zugreifen. Der folgende Screenshot zeigt den Inhalt der Datenbank MySQL:
C:\mysql\bin>mysql --database=dbarticles --user=admarticles --password=mdparticles
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3 to server version: 3.23.49-max-debug
Type 'help' for help.
mysql> show tables;
+----------------------+
| Tables_in_dbarticles |
+----------------------+
| articles |
+----------------------+
1 row in set (0.01 sec)
mysql> select * from articles;
+------+--------------------------------+------+--------------+---------------+
| code | nom | prix | stock_actuel | stock_minimum |
+------+--------------------------------+------+--------------+---------------+
| a300 | vÚlo | 2500 | 10 | 5 |
| b300 | pompe | 56 | 62 | 45 |
| c300 | arc | 3500 | 10 | 20 |
| d300 | flÞches - lot de 6 | 780 | 12 | 20 |
| e300 | combinaison de plongÚe | 2800 | 34 | 7 |
| f300 | bouteilles d'oxygÞne | 800 | 10 | 5 |
+------+--------------------------------+------+--------------+---------------+
6 rows in set (0.02 sec)
mysql> describe articles;
+---------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| code | text | YES | | NULL | |
| nom | text | YES | | NULL | |
| prix | double | YES | | NULL | |
| stock_actuel | smallint(6) | YES | | NULL | |
| stock_minimum | smallint(6) | YES | | NULL | |
+---------------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
mysql> exit
Bye
Um die Basis ACCESS als Datenquelle ODBC zu definieren, gehen Sie wie folgt vor:
- Rufen Sie den Datenquellen-Manager ODBC wie oben gezeigt auf und wählen Sie die Registerkarte „User“ DSN (DSN = Name der Datenquelle)

- Fügen Sie über die Schaltfläche Add eine Quelle hinzu, geben Sie an, dass diese Quelle über einen Treiber Access zugänglich ist, und führen Sie Terminer aus:

- Geben Sie der Datenquelle den Namen articles-access, fügen Sie eine beliebige Beschreibung hinzu und verwenden Sie die Schaltfläche Sélectionner, um die Datei .mdb aus der Datenbank anzugeben. Beenden Sie den Vorgang mit OK.

Die neue Datenquelle erscheint dann in der Liste der Benutzerquellen DSN:

Um die Datenbank MySQL DBARTICLES als Datenquelle ODBC zu definieren, gehen Sie wie folgt vor:
- Öffnen Sie den Datenquellen-Manager ODBC wie oben gezeigt und wählen Sie die Registerkarte „User“ (Benutzer) DSN aus. Fügen Sie eine neue Datenquelle mit Add hinzu und wählen Sie den Treiber ODBC von MySQL aus.

- Führen Sie Terminer aus. Daraufhin erscheint eine Konfigurationsseite für die Quelle MySQL:
54321

- In (1) vergeben wir einen Namen für unsere Datenquelle ODBC
- In (2) geben wir den Rechner an, auf dem sich der Server MySQL befindet. Hier geben wir localhost ein, um anzugeben, dass er sich auf demselben Rechner wie unsere Anwendung befindet. Befände sich der Server MySQL auf einem entfernten Rechner M, würden wir dort dessen Namen eingeben, und unsere Anwendung würde dann ohne Änderungen mit einer entfernten Datenbank arbeiten.
- In (3) geben wir den Namen der Datenbank ein. Hier heißt sie DBARTICLES.
- In (4) geben wir den Benutzernamen admarticles und in (5) das Passwort mdparticles ein.
7.3.2. Verwendung eines Treibers ODBC
In einer Anwendung, die eine Datenbank im verbundenen Modus nutzt, sind in der Regel folgende Schritte erforderlich:
- Verbindung zur Datenbank
- Senden von Abfragen SQL an die Datenbank
- Empfang und Verarbeitung der Ergebnisse dieser Abfragen
- Schließen der Verbindung
Die Schritte 2 und 3 werden wiederholt ausgeführt, wobei das Schließen der Verbindung erst am Ende der Datenbanknutzung erfolgt. Dies ist ein relativ klassisches Schema, mit dem Sie vielleicht bereits vertraut sind, wenn Sie schon einmal eine Datenbank interaktiv genutzt haben. Diese Schritte sind dieselben, unabhängig davon, ob die Datenbank über den Treiber ODBC oder über die Treiber OLE bzw. DB genutzt wird. Im Folgenden stellen wir ein Beispiel mit den Klassen .NET zur Verwaltung der Datenquellen ODBC vor. Das Programm heißt liste und nimmt als Parameter den Namen DSN einer Datenquelle ODBC entgegen, die eine Tabelle ARTICLES enthält. Anschließend zeigt es den Inhalt dieser Tabelle an:
dos>liste
syntaxe : pg dsnArticles
dos>liste articles-access
----------------------------------------
code,nom,prix,stock_actuel,stock_minimum
----------------------------------------
a300 vélo 2500 10 5
b300 pompe 56 62 45
c300 arc 3500 10 20
d300 flèches - lot de 6 780 12 20
e300 combinaison de plongée 2800 34 7
f300 bouteilles d'oxygène 800 10 5
dos>liste mysql-artices
Erreur d'exploitation de la base de données (ERROR [IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified)
dos>liste mysql-articles
----------------------------------------
code,nom,prix,stock_actuel,stock_minimum
----------------------------------------
a300 vélo 2500 10 5
b300 pompe 56 62 45
c300 arc 3500 10 20
d300 flèches - lot de 6 780 12 20
e300 combinaison de plongée 2800 34 7
f300 bouteilles d'oxygène 800 10 5
Aus den obigen Ergebnissen geht hervor, dass das Programm sowohl den Inhalt der Datenbank ACCESS als auch den der Datenbank MySQL aufgelistet hat. Sehen wir uns nun den Code dieses Programms an:
' Optionen
Option Explicit On
Option Strict On
' Namensräume
Imports System
Imports System.Data
Imports Microsoft.Data.Odbc
Imports Microsoft.VisualBasic
Module db1
Sub main(ByVal args As String())
' Konsolenanwendung
' zeigt den Inhalt einer Tabelle ARTICLES aus einer Datenbank DSN an
', deren Name als Parameter übergeben wurde
Const syntaxe As String = "syntaxe : pg dsnArticles"
Const tabArticles As String = "articles" ' la table des articles
' Überprüfung der Parameter
' Gibt es einen Parameter?
If args.Length <> 1 Then
' Fehlermeldung
Console.Error.WriteLine(syntaxe)
' Ende
Environment.Exit(1)
End If
' Der Parameter wird abgerufen
Dim dsnArticles As String = args(0) ' la base DSN
' Vorbereitung der Datenbankverbindung
Dim articlesConn As OdbcConnection = Nothing ' la connexion
Dim myReader As OdbcDataReader = Nothing ' le lecteur de données
' Zugriff auf die Datenbank wird versucht
Try
' Verbindungszeichenfolge zur Datenbank
Dim connectString As String = "DSN=" + dsnArticles + ";"
articlesConn = New OdbcConnection(connectString)
articlesConn.Open()
' Ausführung eines Befehls SQL
Dim sqlText As String = "select * from " + tabArticles
Dim myOdbcCommand As New OdbcCommand(sqlText)
myOdbcCommand.Connection = articlesConn
myReader = myOdbcCommand.ExecuteReader()
' Auswertung der abgerufenen Tabelle
' Anzeige der Spalten
Dim ligne As String = ""
Dim i As Integer
For i = 0 To (myReader.FieldCount - 1) - 1
ligne += myReader.GetName(i) + ","
Next i
ligne += myReader.GetName(i)
Console.Out.WriteLine((ControlChars.Lf + "".PadLeft(ligne.Length, "-"c) + ControlChars.Lf + ligne + ControlChars.Lf + "".PadLeft(ligne.Length, "-"c) + ControlChars.Lf))
' Anzeige der Daten
While myReader.Read()
' Auswertung der aktuellen Zeile
ligne = ""
For i = 0 To myReader.FieldCount - 1
ligne += myReader(i).ToString + " "
Next i
Console.WriteLine(ligne)
End While
Catch ex As Exception
Console.Error.WriteLine(("Erreur d'exploitation de la base de données " + ex.Message + ")"))
Environment.Exit(2)
Finally
' Leser schließen
myReader.Close()
' Verbindung schließen
articlesConn.Close()
End Try
End Sub
End Module
Die Klassen zur Verwaltung der Quellen ODBC befinden sich im Namensraum Microsoft.Data.Odbc, der daher importiert werden muss. Außerdem befinden sich einige Klassen im Namensraum System.Data.
Imports System.Data
Imports Microsoft.Data.Odbc
Die vom Programm verwendeten Namensräume befinden sich in verschiedenen Assemblies. Das Programm wird mit dem folgenden Befehl kompiliert:
dos>vbc /r:microsoft.data.odbc.dll /r:microsoft.visualbasic.dll /r:system.dll /r:system.data.dll db1.vb
7.3.2.1. Die Verbindungsphase
Eine Verbindung ODBC verwendet die Klasse OdbcConnection. Der Konstruktor dieser Klasse akzeptiert als Parameter eine sogenannte Verbindungszeichenfolge. Dabei handelt es sich um eine Zeichenfolge, die alle notwendigen Parameter definiert, damit die Verbindung zur Datenbank hergestellt werden kann. Diese Parameter können sehr zahlreich sein, wodurch die Zeichenfolge komplex werden kann. Die Zeichenfolge hat die Form "param1=valeur1;param2=valeur2;...;paramj=valeurj;". Hier sind einige mögliche Parameter für paramj:
Name eines Benutzers, der auf die Datenbank zugreifen wird | |
Passwort dieses Benutzers | |
Name der Datenbank (falls vorhanden): DSN | |
Name der Datenbank, auf die zugegriffen wird | |
Wenn man eine Datenquelle mithilfe des Datenquellen-Managers ODBC als Datenquelle ODBC definiert, wurden diese Parameter bereits angegeben und gespeichert. Es reicht dann aus, den Parameter DSN zu übergeben, der den Namen DSN der Datenquelle angibt. Dies geschieht hier wie folgt:
' Vorbereitung der Datenbankverbindung
Dim articlesConn As OdbcConnection = Nothing ' la connexion
Dim myReader As OdbcDataReader = Nothing ' le lecteur de données
Try
' Zugriff auf die Datenbank wird versucht
' Verbindungszeichenfolge zur Datenbank
Dim connectString As String = "DSN=" + dsnArticles + ";"
articlesConn = New OdbcConnection(connectString)
articlesConn.Open()
Sobald das Objekt OdbcConnection erstellt ist, wird die Verbindung mit der Methode Open geöffnet. Diese Verbindung kann wie jeder andere Vorgang in der Datenbank fehlschlagen. Aus diesem Grund befindet sich der gesamte Code für den Datenbankzugriff in einem try-catch. Sobald die Verbindung hergestellt ist, können Abfragen vom Typ SQL an die Datenbank gesendet werden.
7.3.2.2. Abfragen vom Typ SQL senden
Um Abfragen vom Typ SQL auszuführen, benötigen wir ein Objekt vom Typ Command, genauer gesagt ein Objekt vom Typ OdbcCommand, da wir eine Datenquelle vom Typ ODBC verwenden. Die Klasse OdbcCommand verfügt über mehrere Konstruktoren:
- OdbcCommand(): Erstellt ein leeres Objekt vom Typ Command. Um es zu verwenden, müssen später verschiedene Eigenschaften festgelegt werden:
- CommandText: der Text der auszuführenden Abfrage SQL
- Connection: das Objekt OdbcConnection, das die Verbindung zur Datenbank darstellt, auf der die Abfrage ausgeführt wird
- CommandType: Der Typ der Abfrage SQL. Es gibt drei mögliche Werte
- CommandType.Text: Die Eigenschaft CommandText enthält den Text einer Abfrage vom Typ SQL (Standardwert)
- CommandType.StoredProcedure: Die Eigenschaft CommandText enthält den Namen einer in der Datenbank gespeicherten gespeicherten Prozedur
- CommandType.TableDirect: Die Eigenschaft CommandText enthält den Namen einer Tabelle T. Entspricht „select * from T“. Existiert nur für die Treiber OLE und DB.
- OdbcCommand(string sqlText): Der Parameter sqlText wird der Eigenschaft CommandText zugewiesen. Dies ist der Text der auszuführenden Abfrage SQL. Die Verbindung muss in der Eigenschaft Connection angegeben werden.
- OdbcCommand(string sqlText, OdbcConnection Verbindung): Der Parameter sqlText wird der Eigenschaft CommandText zugewiesen und der Parameter connexion der Eigenschaft Connection.
Um die Abfrage SQL auszuführen, stehen zwei Methoden zur Verfügung:
- OdbcdataReader ExecuteReader(): sendet die Abfrage SELECT von CommandText an die Verbindung Connection und erstellt ein Objekt OdbcDataReader, das denZugriff auf alle Zeilen der Ergebnistabelle von select
- int ExecuteNOnQuery(): Sendet die Aktualisierungsanfrage (INSERT, UPDATE, DELETE) von CommandText an die Verbindung Connection und gibt die Anzahl der von dieser Aktualisierung betroffenen Zeilen zurück.
In unserem Beispiel senden wir nach dem Öffnen der Datenbankverbindung eine Abfrage SQL SELECT, um den Inhalt der Tabelle ARTICLES abzurufen:
' Ausführung eines Befehls SQL
Dim sqlText As String = "select * from " + tabArticles
Dim myOdbcCommand As New OdbcCommand(sqlText)
myOdbcCommand.Connection = articlesConn
myReader = myOdbcCommand.ExecuteReader()
Eine Abfrage ist in der Regel eine Abfrage vom Typ:
Nur die Schlüsselwörter in der ersten Zeile sind obligatorisch, die anderen sind optional. Es gibt weitere Schlüsselwörter, die hier nicht aufgeführt sind.
- Es wird eine Verknüpfung mit allen Tabellen hergestellt, die hinter dem Schlüsselwort „from“ stehen
- Nur die Spalten, die hinter dem Schlüsselwort „select“ stehen, werden beibehalten
- Es werden nur die Zeilen beibehalten, die die Bedingung des Schlüsselworts „where“ erfüllen
- Die resultierenden Zeilen, sortiert nach dem Ausdruck des Schlüsselworts „order by“, bilden das Ergebnis der Abfrage.
Das Ergebnis von „select“ ist eine Tabelle. Wenn man die vorherige Tabelle „ARTICLES“ betrachtet und die Namen der Artikel ermitteln möchte, deren aktueller Lagerbestand unter dem Mindestschwellenwert liegt, schreibt man:
Wenn man sie in alphabetischer Reihenfolge der Namen haben möchte, schreibt man:
7.3.2.3. Auswertung des Ergebnisses einer Abfrage SELECT
Das Ergebnis einer Abfrage SELECT im Offline-Modus ist ein Objekt DataReader, hier ein Objekt OdbcDataReader. Mit diesem Objekt lassen sich nacheinander alle Zeilen des Ergebnisses abrufen und Informationen zu den Spalten dieser Ergebnisse erhalten. Sehen wir uns einige Eigenschaften und Methoden dieser Klasse an:
die Anzahl der Spalten in der Tabelle | |
Item(i) steht für die Spalte Nr. i der aktuellen Zeile des Ergebnisses | |
Der Wert der Spalte Nr. i der aktuellen Zeile, dargestellt als Typ XXX (Int16, Int32, Int64, Double, String, Boolean, ...) | |
Name der Spalte Nr. i | |
schließt das Objekt OdbcdataReader und gibt die zugehörigen Ressourcen frei | |
Wechselt in der Ergebnistabelle um eine Zeile weiter. Gibt „false“ zurück, wenn dies nicht möglich ist. Die neue Zeile wird zur aktuellen Zeile des Lesers. |
Die Auswertung des Ergebnisses eines select erfolgt typischerweise sequenziell, ähnlich wie bei Textdateien: Man kann sich in der Tabelle nur vorwärts bewegen, nicht rückwärts:
While myReader.Read()
' Es liegt eine Zeile vor – diese wird ausgewertet
....
' nächste Zeile
end while
Diese Erläuterungen reichen aus, um den folgenden Code aus unserem Beispiel zu verstehen:
' Auswertung der abgerufenen Tabelle
' Anzeige der Spalten
Dim ligne As String = ""
Dim i As Integer
For i = 0 To (myReader.FieldCount - 1) - 1
ligne += myReader.GetName(i) + ","
Next i
ligne += myReader.GetName(i)
Console.Out.WriteLine((ControlChars.Lf + "".PadLeft(ligne.Length, "-"c) + ControlChars.Lf + ligne + ControlChars.Lf + "".PadLeft(ligne.Length, "-"c) + ControlChars.Lf))
' Anzeige der Daten
While myReader.Read()
' Auswertung der aktuellen Zeile
ligne = ""
For i = 0 To myReader.FieldCount - 1
ligne += myReader(i).ToString + " "
Next i
Console.WriteLine(ligne)
End While
Die einzige Schwierigkeit liegt in der Anweisung, in der die Werte der verschiedenen Spalten der aktuellen Zeile verkettet werden:
For i = 0 To myReader.FieldCount - 1
ligne += myReader(i).ToString + " "
Next i
Die Notation „Zeile+=myReader(i).ToString“ wird übersetzt als „Zeile+=myReader.Item(i)“.ToString(), wobei Item(i) der Wert der Spalte i der aktuellen Zeile ist.
7.3.2.4. Freigabe von Ressourcen
Die Klassen OdbcReader und OdbcConnection verfügen beide über eine Methode Close(), die die mit den so geschlossenen Objekten verbundenen Ressourcen freigibt.
7.3.3. Verwendung eines Treibers OLE DB
Wir greifen dasselbe Beispiel wieder auf, diesmal mit einer Datenbank, auf die über einen Treiber OLE DB zugegriffen wird. Die Plattform .NET stellt einen solchen Treiber für Datenbanken vom Typ ACCESS bereit. Daher verwenden wir dieselbe Datenbank articles.mdb wie zuvor. Wir möchten hier zeigen, dass sich zwar die Klassen ändern, die Konzepte jedoch dieselben bleiben:
- Die Verbindung wird durch ein Objekt OleDbConnection dargestellt
- eine Abfrage SQL wird mithilfe eines Objekts OleDbCommand gesendet
- Wenn es sich bei dieser Abfrage um eine Klausel SELECT handelt, wird als Rückgabewert ein Objekt OleDbDataReader zurückgegeben, um auf die Zeilen der Ergebnistabelle zuzugreifen
Diese Klassen befinden sich im Namensraum System.Data.OleDb. Das vorstehende Programm lässt sich leicht so umgestalten, dass es eine Datenbank vom Typ OLE DB verarbeitet:
- Man ersetzt überall OdbcXX durch OleDbXX
- die Verbindungszeichenfolge wird angepasst. Für eine Datenbank mit der Kennung ACCESS ohne Login/Passwort lautet die Verbindungszeichenfolge Provider=Microsoft.JET.OLEDB.4.0;Data Source=[fichier.mdb]. Der konfigurierbare Teil dieser Zeichenfolge ist der Name der zu verwendenden Datei ACCESS. Wir werden unser Programm so anpassen, dass es den Namen dieser Datei als Parameter akzeptiert.
- Der zu importierende Namespace lautet nun System.Data.OleDb.
Unser Programm sieht nun wie folgt aus:
' Optionen
Option Explicit On
Option Strict On
' Namensräume
Imports System
Imports System.Data
Imports Microsoft.Data.Odbc
Imports Microsoft.VisualBasic
Imports System.Data.OleDb
Module db2
Public Sub Main(ByVal args() As String)
' Konsolenanwendung
' zeigt den Inhalt einer Tabelle ARRTICLES aus einer Datenbank DSN an
', deren Name als Parameter übergeben wurde
Const syntaxe As String = "syntaxe : pg base_access_articles"
Const tabArticles As String = "articles" ' la table des articles
' Überprüfung der Parameter
' Gibt es einen Parameter?
If args.Length <> 1 Then
' Fehlermeldung
Console.Error.WriteLine(syntaxe)
' Ende
Environment.Exit(1)
End If
' Parameter wird abgerufen
Dim dbArticles As String = args(0) ' la base de données
' Vorbereitung der Datenbankverbindung
Dim articlesConn As OleDbConnection = Nothing ' la connexion
Dim myReader As OleDbDataReader = Nothing ' le lecteur de données
' Zugriff auf die Datenbank wird versucht
Try
' Verbindungszeichenfolge zur Datenbank
Dim connectString As String = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=" + dbArticles + ";"
articlesConn = New OleDbConnection(connectString)
articlesConn.Open()
' Ausführung eines Befehls SQL
Dim sqlText As String = "select * from " + tabArticles
Dim myOleDbCommand As New OleDbCommand(sqlText)
myOleDbCommand.Connection = articlesConn
myReader = myOleDbCommand.ExecuteReader()
' Auswertung der abgerufenen Tabelle
' Anzeige der Spalten
Dim ligne As String = ""
Dim i As Integer
For i = 0 To (myReader.FieldCount - 1) - 1
ligne += myReader.GetName(i) + ","
Next i
ligne += myReader.GetName(i)
Console.Out.WriteLine((ControlChars.Lf + "".PadLeft(ligne.Length, "-"c) + ControlChars.Lf + ligne + ControlChars.Lf + "".PadLeft(ligne.Length, "-"c) + ControlChars.Lf))
' Anzeige der Daten
While myReader.Read()
' Auswertung der aktuellen Zeile
ligne = ""
For i = 0 To myReader.FieldCount - 1
ligne += myReader(i).ToString + " "
Next i
Console.WriteLine(ligne)
End While
Catch ex As Exception
Console.Error.WriteLine(("Erreur d'exploitation de la base de données (" + ex.Message + ")"))
Environment.Exit(2)
Finally
' Leser schließen
myReader.Close()
' Verbindung schließen
articlesConn.Close()
End Try
' Ende
Environment.Exit(0)
End Sub
End Module
Die erzielten Ergebnisse:
dos>vbc liste.vb
E:\data\serge\MSNET\vb.net\adonet\6>dir
07/05/2002 15:09 2 325 liste.CS
07/05/2002 15:09 4 608 liste.exe
20/08/2001 11:54 86 016 ARTICLES.MDB
dos>liste articles.mdb
----------------------------------------
code,nom,prix,stock_actuel,stock_minimum
----------------------------------------
a300 vélo 2500 10 5
b300 pompe 56 62 45
c300 arc 3500 10 20
d300 flèches - lot de 6 780 12 20
e300 combinaison de plongée 2800 34 7
f300 bouteilles d'oxygène 800 10 5
7.3.4. Aktualisierung einer Tabelle
In den vorangegangenen Beispielen wurde lediglich der Inhalt einer Tabelle aufgelistet. Wir passen unser Programm zur Verwaltung der Artikelstammdaten so an, dass es diese auch ändern kann. Das Programm heißt sql. Als Parameter wird ihm der Name DSN der zu verwaltenden Artikelstammdaten übergeben. Der Benutzer gibt die Befehle SQL direkt über die Tastatur ein, und das Programm führt sie aus, wie die folgenden Ergebnisse zeigen, die anhand der Artikelstammdatenbank MySQL erzielt wurden:
dos>vbc /r:microsoft.data.odbc.dll sql.vb
dos>sql mysql-articles
Requête SQL (fin pour arrêter) : select * from articles
----------------------------------------
code,nom,prix,stock_actuel,stock_minimum
----------------------------------------
a300 vélo 2500 10 5
b300 pompe 56 62 45
c300 arc 3500 10 20
d300 flèches - lot de 6 780 12 20
e300 combinaison de plongée 2800 34 7
f300 bouteilles d'oxygène 800 10 5
Requête SQL (fin pour arrêter) : select * from articles where stock_actuel<stock_minimum
----------------------------------------
code,nom,prix,stock_actuel,stock_minimum
----------------------------------------
c300 arc 3500 10 20
d300 flèches - lot de 6 780 12 20
Requête SQL (fin pour arrêter) : insert into articles values ("1","1",1,1,1)
Il y a eu 1 ligne(s) modifiée(s)
Requête SQL (fin pour arrêter) : select * from articles
----------------------------------------
code,nom,prix,stock_actuel,stock_minimum
----------------------------------------
a300 vélo 2500 10 5
b300 pompe 56 62 45
c300 arc 3500 10 20
d300 flèches - lot de 6 780 12 20
e300 combinaison de plongée 2800 34 7
f300 bouteilles d'oxygène 800 10 5
1 1 1 1 1
Requête SQL (fin pour arrêter) : update articles set nom="2" where nom="1"
Il y a eu 1 ligne(s) modifiée(s)
Requête SQL (fin pour arrêter) : select * from articles
----------------------------------------
code,nom,prix,stock_actuel,stock_minimum
----------------------------------------
a300 vélo 2500 10 5
b300 pompe 56 62 45
c300 arc 3500 10 20
d300 flèches - lot de 6 780 12 20
e300 combinaison de plongée 2800 34 7
f300 bouteilles d'oxygène 800 10 5
1 2 1 1 1
Requête SQL (fin pour arrêter) : delete from articles where code="1"
Il y a eu 1 ligne(s) modifiée(s)
Requête SQL (fin pour arrêter) : select * from articles
----------------------------------------
code,nom,prix,stock_actuel,stock_minimum
----------------------------------------
a300 vélo 2500 10 5
b300 pompe 56 62 45
c300 arc 3500 10 20
d300 flèches - lot de 6 780 12 20
e300 combinaison de plongée 2800 34 7
f300 bouteilles d'oxygène 800 10 5
Requête SQL (fin pour arrêter) : select * from articles order by nom asc
----------------------------------------
code,nom,prix,stock_actuel,stock_minimum
----------------------------------------
c300 arc 3500 10 20
f300 bouteilles d'oxygène 800 10 5
e300 combinaison de plongée 2800 34 7
d300 flèches - lot de 6 780 12 20
b300 pompe 56 62 45
a300 vélo 2500 10 5
Requête SQL (fin pour arrêter) : fin
Das Programm sieht wie folgt aus:
' Optionen
Option Explicit On
Option Strict On
' Namensräume
Imports System
Imports System.Data
Imports Microsoft.Data.Odbc
Imports System.Data.OleDb
Imports System.Text.RegularExpressions
Imports System.Collections
Imports Microsoft.VisualBasic
Module db3
Public Sub Main(ByVal args() As String)
' Konsolenanwendung
' führt über die Tastatur eingegebene Abfragen SQL auf einer
' Tabelle ARTICLES einer Datenbank DSN, deren Name als Parameter übergeben wird
Const syntaxe As String = "syntaxe : pg dsnArticles"
' Überprüfung der Parameter
' Gibt es 2 Parameter?
If args.Length <> 1 Then
' Fehlermeldung
Console.Error.WriteLine(syntaxe)
' Ende
Environment.Exit(1)
End If 'if
' Parameter wird abgerufen
Dim dsnArticles As String = args(0)
' Verbindungszeichenfolge zur Datenbank
Dim connectString As String = "DSN=" + dsnArticles + ";"
' Vorbereitung der Datenbankverbindung
Dim articlesConn As OdbcConnection = Nothing
Dim sqlCommand As OdbcCommand = Nothing
Try
' Versuch, auf die Datenbank zuzugreifen
articlesConn = New OdbcConnection(connectString)
articlesConn.Open()
' ein Befehlsobjekt wird erstellt
sqlCommand = New OdbcCommand("", articlesConn)
'try
Catch ex As Exception
' Fehlermeldung
Console.Error.WriteLine(("Erreur d'exploitation de la base de données (" + ex.Message + ")"))
' Freigabe der Ressourcen
Try
articlesConn.Close()
Catch
End Try
Environment.Exit(2)
End Try 'catch
' Es wird ein Verzeichnis der akzeptierten SQL-Befehle erstellt
Dim commandesSQL() As String = {"select", "insert", "update", "delete"}
Dim dicoCommandes As New Hashtable
Dim i As Integer
For i = 0 To commandesSQL.Length - 1
dicoCommandes.Add(commandesSQL(i), True)
Next i
' Einlesen und Ausführen der über die Tastatur eingegebenen Befehle SQL
Dim requête As String = Nothing ' texte de la requête SQL
Dim champs() As String ' les champs de la requête
Dim modèle As New Regex("\s+")
' Schleife zum Eingeben und Ausführen der über die Tastatur eingegebenen Befehle SQL
While True
' Zunächst keine Fehler
Dim erreur As Boolean = False
' Abfrage der Anfrage
Console.Out.Write(ControlChars.Lf + "Requête SQL (fin pour arrêter) : ")
requête = Console.In.ReadLine().Trim().ToLower()
' Fertig?
If requête = "fin" Then
Exit While
End If
' Die Abfrage wird in Felder zerlegt
champs = modèle.Split(requête)
' Gültige Anfrage?
If champs.Length = 0 Or Not dicoCommandes.ContainsKey(champs(0)) Then
' Fehlermeldung
Console.Error.WriteLine("Requête invalide. Utilisez select, insert, update, delete")
' Nächste Abfrage
erreur = True
End If
If Not erreur Then
' Vorbereitung des Command-Objekts zur Ausführung der Abfrage
sqlCommand.CommandText = requête
' Ausführung der Anfrage
Try
If champs(0) = "select" Then
executeSelect(sqlCommand)
Else
executeUpdate(sqlCommand)
End If
Catch ex As Exception
' Fehlermeldung
Console.Error.WriteLine(("Erreur d'exploitation de la base de données (" + ex.Message + ")"))
End Try
End If
End While
' Freigabe der Ressourcen
Try
articlesConn.Close()
Catch
End Try
Environment.Exit(0)
End Sub
' Ausführung einer Aktualisierungsanfrage
Sub executeUpdate(ByVal sqlCommand As OdbcCommand)
' führt sqlCommand aus, Aktualisierungsabfrage
Dim nbLignes As Integer = sqlCommand.ExecuteNonQuery()
' Anzeige
Console.Out.WriteLine(("Il y a eu " & nbLignes & " ligne(s) modifiée(s)"))
End Sub
' Ausführung einer Select-Abfrage
Sub executeSelect(ByVal sqlCommand As OdbcCommand)
' führt sqlCommand aus, Select-Abfrage
Dim myReader As OdbcDataReader = sqlCommand.ExecuteReader()
' Auswertung der abgerufenen Tabelle
' Anzeige der Spalten
Dim ligne As String = ""
Dim i As Integer
For i = 0 To (myReader.FieldCount - 1) - 1
ligne += myReader.GetName(i) + ","
Next i
ligne += myReader.GetName(i)
Console.Out.WriteLine((ControlChars.Lf + "".PadLeft(ligne.Length, "-"c) + ControlChars.Lf + ligne + ControlChars.Lf + "".PadLeft(ligne.Length, "-"c) + ControlChars.Lf))
' Anzeige der Daten
While myReader.Read()
' Auswertung der aktuellen Zeile
ligne = ""
For i = 0 To myReader.FieldCount - 1
ligne += myReader(i).ToString + " "
Next i
' Anzeige
Console.WriteLine(ligne)
End While
' Freigabe der Ressourcen
myReader.Close()
End Sub
End Module
Wir gehen hier nur auf die Neuerungen gegenüber dem vorherigen Programm ein:
- Wir erstellen ein Wörterbuch der akzeptierten SQL-Befehle:
' Es wird ein Verzeichnis der akzeptierten SQL-Befehle erstellt
Dim commandesSQL() As String = {"select", "insert", "update", "delete"}
Dim dicoCommandes As New Hashtable
Dim i As Integer
For i = 0 To commandesSQL.Length - 1
dicoCommandes.Add(commandesSQL(i), True)
Next i
Dadurch können wir anschließend ganz einfach überprüfen, ob das erste Wort (Feld [0]) der eingegebenen Abfrage einer der vier zulässigen Befehle ist:
' Gültige Abfrage?
If champs.Length = 0 Or Not dicoCommandes.ContainsKey(champs(0)) Then
' Fehlermeldung
Console.Error.WriteLine("Requête invalide. Utilisez select, insert, update, delete")
' Nächste Abfrage
erreur = True
End If 'if
- Zuvor war die Abfrage mithilfe der Methode Split der Klasse RegEx in Felder zerlegt worden:
Dim modèle As New Regex("\s+")
....
' Die Abfrage wird in Felder zerlegt
champs = modèle.Split(requête)
Die Wörter, aus denen die Abfrage besteht, können durch beliebig viele Leerzeichen voneinander getrennt sein.
- Die Ausführung einer Abfrage select erfolgt nicht nach dem gleichen Verfahren wie die einer Aktualisierungsabfrage (insert, update, delete). Daher muss ein Test durchgeführt und für jeden dieser beiden Fälle eine andere Funktion ausgeführt werden:
' Vorbereitung des Command-Objekts zur Ausführung der Abfrage
sqlCommand.CommandText = requête
' Ausführung der Abfrage
Try
If champs(0) = "select" Then
executeSelect(sqlCommand)
Else
executeUpdate(sqlCommand)
End If 'try
Catch ex As Exception
' Fehlermeldung
Console.Error.WriteLine(("Erreur d'exploitation de la base de données (" + ex.Message + ")"))
End Try
Die Ausführung einer Abfrage SQL kann eine Ausnahme auslösen, die hier behandelt wird.
- Die Funktion executeSelect greift alles auf, was in den vorherigen Beispielen behandelt wurde.
- Die Funktion executeUpdate nutzt die Methode ExecuteNonQuery der Klasse OdbcCommand, die die Anzahl der vom Befehl betroffenen Zeilen zurückgibt.
7.3.5. IMPOTS
Wir greifen das in einem vorherigen Kapitel erstellte Objekt impôt wieder auf:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Public Class impôt
' die für die Steuerberechnung erforderlichen Daten
' stammen aus einer externen Quelle
Private limites(), coeffR(), coeffN() As Decimal
' Hersteller
Public Sub New(ByVal LIMITES() As Decimal, ByVal COEFFR() As Decimal, ByVal COEFFN() As Decimal)
' Es wird überprüft, ob alle drei Tabellen dieselbe Größe haben
Dim OK As Boolean = LIMITES.Length = COEFFR.Length And LIMITES.Length = COEFFN.Length
If Not OK Then
Throw New Exception("Les 3 tableaux fournis n'ont pas la même taille(" & LIMITES.Length & "," & COEFFR.Length & "," & COEFFN.Length & ")")
End If
' alles in Ordnung
Me.limites = LIMITES
Me.coeffR = COEFFR
Me.coeffN = COEFFN
End Sub
' Berechnung der Steuer
Public Function calculer(ByVal marié As Boolean, ByVal nbEnfants As Integer, ByVal salaire As Integer) As Long
' Berechnung der Anzahl der Anteile
Dim nbParts As Decimal
If marié Then
nbParts = CDec(nbEnfants) / 2 + 2
Else
nbParts = CDec(nbEnfants) / 2 + 1
End If
If nbEnfants >= 3 Then
nbParts += 0.5D
End If
' Berechnung des zu versteuernden Einkommens und des Familienquotienten
Dim revenu As Decimal = 0.72D * salaire
Dim QF As Decimal = revenu / nbParts
' Steuerberechnung
limites((limites.Length - 1)) = QF + 1
Dim i As Integer = 0
While QF > limites(i)
i += 1
End While
' Ergebnisrückgabe
Return CLng(revenu * coeffR(i) - nbParts * coeffN(i))
End Function
End Class
Wir fügen ihm einen neuen Konstruktor hinzu, mit dem die Arrays limites, coeffR und coeffN aus einer Datenbank ODBC initialisiert werden können:
Imports System.Data
Imports Microsoft.Data.Odbc
Imports System.Collections
...
' Konstruktor 2
Public Sub New(ByVal DSNimpots As String, ByVal Timpots As String, ByVal colLimites As String, ByVal colCoeffR As String, ByVal colCoeffN As String)
' Initialisiert die drei Grenzwerttabellen coeffR, coeffN anhand
' des Inhalts der Tabelle „Timpots“ aus der Datenbank ODBC DSNimpots
' colLimites, colCoeffR, colCoeffN sind die drei Spalten dieser Tabelle
' kann eine Ausnahme auslösen
Dim connectString As String = "DSN=" + DSNimpots + ";" ' chaîne de connexion à la base
Dim impotsConn As OdbcConnection = Nothing ' la connexion
Dim sqlCommand As OdbcCommand = Nothing ' la commande SQL
' die Abfrage SELECT
Dim selectCommand As String = "select " + colLimites + "," + colCoeffR + "," + colCoeffN + " from " + Timpots
' Tabellen zum Abrufen der Daten
Dim tLimites As New ArrayList
Dim tCoeffR As New ArrayList
Dim tCoeffN As New ArrayList
' Es wird versucht, auf die Datenbank zuzugreifen
impotsConn = New OdbcConnection(connectString)
impotsConn.Open()
' ein Befehlsobjekt wird erstellt
sqlCommand = New OdbcCommand(selectCommand, impotsConn)
' Die Abfrage wird ausgeführt
Dim myReader As OdbcDataReader = sqlCommand.ExecuteReader()
' Auswertung der abgerufenen Tabelle
While myReader.Read()
' Die Daten der aktuellen Zeile werden in die Arrays übertragen
tLimites.Add(myReader(colLimites))
tCoeffR.Add(myReader(colCoeffR))
tCoeffN.Add(myReader(colCoeffN))
End While
' Freigabe der Ressourcen
myReader.Close()
impotsConn.Close()
' Die dynamischen Arrays werden in statische Arrays übertragen
Me.limites = New Decimal(tLimites.Count) {}
Me.coeffR = New Decimal(tLimites.Count) {}
Me.coeffN = New Decimal(tLimites.Count) {}
Dim i As Integer
For i = 0 To tLimites.Count - 1
limites(i) = Decimal.Parse(tLimites(i).ToString())
coeffR(i) = Decimal.Parse(tCoeffR(i).ToString())
coeffN(i) = Decimal.Parse(tCoeffN(i).ToString())
Next i
End Sub
Das Testprogramm läuft wie folgt ab: Es erhält als Argumente die Parameter, die an den Konstruktor der Klasse impôt übergeben werden sollen. Nach der Erstellung eines Objekts vom Typ impôt führt es Berechnungen zur zu zahlenden Steuer durch:
Option Explicit On
Option Strict On
' Namensräume
Imports System
Imports Microsoft.VisualBasic
' Test-PG
Module testimpots
Sub Main(ByVal arguments() As String)
' Interaktives Programm zur Steuerberechnung
' Der Benutzer gibt drei Daten über die Tastatur ein: verheiratet nbEnfants Gehalt
' Das Programm zeigt daraufhin die zu zahlende Steuer an
Const syntaxe1 As String = "pg DSNimpots tabImpots colLimites colCoeffR colCoeffN"
Const syntaxe2 As String = "syntaxe : marié nbEnfants salaire" + ControlChars.Lf + "marié : o pour marié, n pour non marié" + ControlChars.Lf + "nbEnfants : nombre d'enfants" + ControlChars.Lf + "salaire : salaire annuel en F"
' Überprüfung der Programmparameter
If arguments.Length <> 5 Then
' Fehlermeldung
Console.Error.WriteLine(syntaxe1)
' Ende
Environment.Exit(1)
End If 'if
' die Argumente werden abgerufen
Dim DSNimpots As String = arguments(0)
Dim tabImpots As String = arguments(1)
Dim colLimites As String = arguments(2)
Dim colCoeffR As String = arguments(3)
Dim colCoeffN As String = arguments(4)
' Erstellung eines Steuerobjekts
Dim objImpôt As impôt = Nothing
Try
objImpôt = New impôt(DSNimpots, tabImpots, colLimites, colCoeffR, colCoeffN)
Catch ex As Exception
Console.Error.WriteLine(("L'erreur suivante s'est produite : " + ex.Message))
Environment.Exit(2)
End Try
' Endlosschleife
While True
' zunächst keine Fehler
Dim erreur As Boolean = False
' die Parameter für die Steuerberechnung werden abgefragt
Console.Out.Write("Paramètres du calcul de l'impôt au format marié nbEnfants salaire ou rien pour arrêter :")
Dim paramètres As String = Console.In.ReadLine().Trim()
' Was ist zu tun?
If paramètres Is Nothing Or paramètres = "" Then
Exit While
End If
' Überprüfung der Anzahl der Argumente in der eingegebenen Zeile
Dim args As String() = paramètres.Split(Nothing)
Dim nbParamètres As Integer = args.Length
If nbParamètres <> 3 Then
Console.Error.WriteLine(syntaxe2)
erreur = True
End If
Dim marié As String
Dim nbEnfants As Integer
Dim salaire As Integer
If Not erreur Then
' Überprüfung der Gültigkeit der Parameter
' verheiratet
marié = args(0).ToLower()
If marié <> "o" And marié <> "n" Then
Console.Error.WriteLine((syntaxe2 + ControlChars.Lf + "Argument marié incorrect : tapez o ou n"))
erreur = True
End If
' nbEnfants
nbEnfants = 0
Try
nbEnfants = Integer.Parse(args(1))
If nbEnfants < 0 Then
Throw New Exception
End If
Catch
Console.Error.WriteLine(syntaxe2 + "\nArgument nbEnfants incorrect : tapez un entier positif ou nul")
erreur = True
End Try
' Gehalt
salaire = 0
Try
salaire = Integer.Parse(args(2))
If salaire < 0 Then
Throw New Exception
End If
Catch
Console.Error.WriteLine(syntaxe2 + "\nArgument salaire incorrect : tapez un entier positif ou nul")
erreur = True
End Try
End If
If Not erreur Then
' Die Parameter sind korrekt – die Steuer wird berechnet
Console.Out.WriteLine(("impôt=" & objImpôt.calculer(marié = "o", nbEnfants, salaire).ToString + " F"))
End If
End While
End Sub
End Module
Als Basis wird eine Datenbank mit dem Namen DSN mysql-impots verwendet:
C:\mysql\bin>mysql --database=impots --user=admimpots --password=mdpimpots
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5 to server version: 3.23.49-max-debug
Type 'help' for help.
mysql> show tables;
+------------------+
| Tables_in_impots |
+------------------+
| timpots |
+------------------+
mysql> select * from timpots;
+---------+--------+---------+
| limites | coeffR | coeffN |
+---------+--------+---------+
| 12620 | 0 | 0 |
| 13190 | 0.05 | 631 |
| 15640 | 0.1 | 1290.5 |
| 24740 | 0.15 | 2072.5 |
| 31810 | 0.2 | 3309.5 |
| 39970 | 0.25 | 4900 |
| 48360 | 0.3 | 6898 |
| 55790 | 0.35 | 9316.5 |
| 92970 | 0.4 | 12106 |
| 127860 | 0.45 | 16754 |
| 151250 | 0.5 | 23147.5 |
| 172040 | 0.55 | 30710 |
| 195000 | 0.6 | 39312 |
| 0 | 0.65 | 49062 |
+---------+--------+---------+
Die Ausführung des Testprogramms liefert folgende Ergebnisse:
dos>D:\data\devel\vbnet\poly\chap6\impots>vbc /r:system.data.dll /r:microsoft.data.odbc.dll /r:system.dll /t:library impots.vb
dos>vbc /r:impots.dll testimpots.vb
dos>test mysql-impots timpots limites coeffr coeffn
Paramètres du calcul de l'impôt au format marié nbEnfants salaire ou rien pour arrêter :o 2 200000
impôt=22506 F
Paramètres du calcul de l'impôt au format marié nbEnfants salaire ou rien pour arrêter :n 2 200000
impôt=33388 F
Paramètres du calcul de l'impôt au format marié nbEnfants salaire ou rien pour arrêter :o 3 200000
impôt=16400 F
Paramètres du calcul de l'impôt au format marié nbEnfants salaire ou rien pour arrêter :n 3 300000
impôt=50082 F
Paramètres du calcul de l'impôt au format marié nbEnfants salaire ou rien pour arrêter :n 3 200000
impôt=22506 F
Paramètres du calcul de l'impôt au format marié nbEnfants salaire ou rien pour arrêter :
