Skip to content

7. Veritabanlarına erişim

7.1. Genel Bilgiler

Windows platformları için çok sayıda veritabanı bulunmaktadır. Bu veritabanlarına erişmek için uygulamalar, sürücü (driver) adı verilen programlar aracılığıyla çalışır.

Yukarıdaki şemada, sürücünün iki arayüzü bulunmaktadır:

  • uygulamaya sunulan I1 arayüzü
  • veritabanına yönelik I2 arayüzü

B1 veritabanı için yazılmış bir uygulamanın, farklı bir B2 veritabanına geçiş yapıldığında yeniden yazılması gerekmemesi için, I1 arayüzünde bir standardizasyon çalışması yapılmıştır. "Standartlaştırılmış" sürücüler kullanan veritabanları kullanılıyorsa, B1 veritabanı P1 sürücüsüyle, B2 veritabanı ise P2 sürücüsüyle birlikte sağlanacaktır ve bu iki sürücünün I1 arayüzü aynı olacaktır. Böylece uygulamayı yeniden yazmaya gerek kalmayacaktır. Böylece, örneğin, uygulamayı değiştirmeden bir ACCESS veritabanını bir MySQL veritabanına taşıyabiliriz.

İki tür standart sürücü bulunmaktadır:

  • ODBC sürücüleri (Open DataBase Connectivity)
  • OLE ve DB sürücüleri (Object Linking and Embedding DataBase)

ODBC sürücüleri, veritabanlarına erişim sağlar. OLE ve DB sürücüleri için veri kaynakları daha çeşitlidir: veritabanları, e-posta sistemleri, adres defterleri vb. Herhangi bir sınırlama yoktur. Yazılım geliştiricisi karar verirse, herhangi bir veri kaynağı OLE ve DB sürücülerinin konusu olabilir. Bunun faydası elbette çok büyüktür: çok çeşitli verilere tek tip bir erişim sağlanır.

.NET platformu, iki tür veri erişim sınıfıyla birlikte sunulur:

  1. SQL ve Server.NET sınıfları
  2. OLE ve Db.NET sınıfları

İlk sınıflar, ara sürücü olmadan Microsoft SGBD SQL Sunucusuna doğrudan erişim sağlar. İkinci sınıflar ise OLE DB veri kaynaklarına erişim sağlar.

Image

.NET platformu (Mayıs 2002), sırasıyla OLE, DB ve SQL Sunucu, Oracle ve Microsoft Jet (Access) için üç sürücü ile birlikte sunulmaktadır. ODBC sürücüsüne sahip ancak OLE ve DB sürücülerine sahip olmayan bir veritabanıyla çalışmak istenirse, bu mümkün değildir. Dolayısıyla, (Mayıs 2002 itibarıyla) OLE ve DB sürücülerini sağlamayan SGBD ve MySQL ile çalışamazsınız. Bununla birlikte, ODBC veri kaynaklarına erişim sağlayan bir dizi sınıf mevcuttur: odbc.net sınıfları. Bu sınıflar SDK ile standart olarak sunulmaz ve Microsoft'un web sitesinden indirilmesi gerekir. Aşağıdaki örneklerde, özellikle bu ODBC sınıflarını kullanacağız; çünkü Windows altındaki çoğu veritabanı, bu tür bir sürücüyle birlikte gelir. Örneğin, bir Win 2000 bilgisayarında yüklü olan ODBC sürücülerinin listesi şöyledir (Başlat Menüsü/Ayarlar/Denetim Masası/Yönetim Araçları):

Image

ODBC Veri Kaynağı simgesini seçin:

Image

7.2. Bir veri kaynağının iki çalışma modu

.NET platformu, bir veri kaynağının iki farklı şekilde kullanılmasını sağlar:

  1. çevrimiçi mod
  2. çevrimdışı mod

Bağlı modda, uygulama

  1. veri kaynağıyla bir bağlantı kurar
  2. veri kaynağıyla okuma/yazma işlemlerini gerçekleştirir
  3. bağlantıyı kapatır

Çevrimdışı modda, uygulama

  1. veri kaynağıyla bir bağlantı kurar
  2. kaynağın verilerinin tamamının veya bir kısmının bellek kopyasını alır
  3. bağlantıyı kapatır
  4. verilerin bellek kopyası üzerinde okuma/yazma işlemlerini gerçekleştirir
  5. iş bittiğinde, bir bağlantı açar, değiştirilen verileri veri kaynağına gönderir ve kaynağın bunları dikkate almasını sağlar, ardından bağlantıyı kapatır

Her iki durumda da, zaman alan işlem verilerin işlenmesi ve güncellenmesidir. Bu güncellemelerin veri girişi yapan bir kullanıcı tarafından yapıldığını düşünürsek, bu işlem onlarca dakika sürebilir. Tüm bu süre boyunca, çevrimiçi modda veritabanıyla bağlantı sürdürülür ve değişiklikler anında yansıtılır. Çevrimdışı modda ise, verilerin güncellenmesi sırasında veritabanına bağlantı yoktur. Değişiklikler yalnızca bellek kopyasında yapılır. Her şey tamamlandığında, değişiklikler tek seferde veri kaynağına yansıtılır.

Bu iki yöntemin avantajları ve dezavantajları nelerdir?

  • Bir bağlantı, sistem kaynaklarını yoğun şekilde tüketir. Eşzamanlı bağlantı sayısı çok fazla olduğunda, çevrimdışı mod, bağlantı sürelerini en aza indirmeye olanak tanır. Binlerce kullanıcısı olan web uygulamalarında durum böyledir.
  • Çevrimdışı modun dezavantajı, eşzamanlı güncellemelerin yönetiminin zor olmasıdır. U1 kullanıcısı, T1 zamanında verileri alır ve bunları değiştirmeye başlar. T2 zamanında, U2 kullanıcısı da veri kaynağına erişir ve aynı verileri alır. Bu arada U1 kullanıcısı bazı verileri değiştirmiştir ancak bunları henüz veri kaynağına iletmemiştir. Dolayısıyla U2, bazıları hatalı olan verilerle çalışmaktadır. .NET sınıfları bu sorunu yönetmek için çözümler sunar, ancak bu sorunun çözümü kolay değildir.
  • Bağlı modda, birden fazla kullanıcı tarafından verilerin eşzamanlı olarak güncellenmesi normalde bir sorun oluşturmaz. Veritabanıyla bağlantı sürdüğü için, bu eşzamanlı güncellemeleri veritabanının kendisi yönetir. Bu nedenle Oracle, bir kullanıcı veritabanındaki bir satırı değiştirdiğinde bu satırı kilitler. Değişikliği yapan kullanıcı, değişikliğini onaylayana (commit) veya geri alana (rollback) kadar satır kilitli kalır ve diğer kullanıcılar tarafından erişilemez.
  • Verilerin ağ üzerinden aktarılması gerekiyorsa, çevrimdışı mod tercih edilmelidir. Bu mod, tek başına bir veritabanını temsil eden “dataset” adlı bir nesne içinde verilerin bir anlık görüntüsünü elde etmeyi sağlar. Bu nesne, ağ üzerinden makineler arasında aktarılabilir.

Öncelikle çevrimiçi modu inceleyeceğiz.

7.3. Bağlantılı modda verilere erişim

7.3.1. Örnekteki veritabanları

ACCESS adlı, articles.mdb olarak adlandırılan ve aşağıdaki yapıya sahip ARTICLES adlı tek bir tablo içeren bir veritabanını ele alıyoruz:

ad
tür
kod
4 karakterlik ürün kodu
ad
adı (karakter dizisi)
fiyat
fiyatı (gerçek)
stock_actuel
mevcut stok (tamsayı)
stock_minimum
ürünün yeniden stoklanması gereken minimum stok miktarı (tamsayı)

Başlangıç içeriği şöyledir:

Image

Bu verileri hem ODBC pilotu hem deOLE DB pilotu aracılığıyla da kullanacağız; bunun nedeni, iki yaklaşımın benzerliğini göstermek ve ACCESS için bu iki tür pilota sahip olmamızdır.

Ayrıca, aynı tek tabloya (ARTICLES) sahip olan MySQL ve DBARTICLES veritabanlarını da kullanacağız; aynı içeriğe sahip ve ODBC sürücüsü aracılığıyla erişilen bir veritabanı kullanacağız; böylece, ACCESS veritabanını kullanmak üzere yazılmış uygulamanın, MySQL veritabanını kullanmak için değiştirilmesine gerek olmadığını göstereceğiz. DBARTICLES veritabanına, admarticles adlı kullanıcı, mdparticles şifresiyle erişebilir. Aşağıdaki ekran görüntüsü, MySQL veritabanının içeriğini göstermektedir:

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

ACCESS veritabanını ODBC veri kaynağı olarak tanımlamak için aşağıdaki adımları izleyin:

  • Yukarıda gösterildiği gibi ODBC veri kaynağı yöneticisini etkinleştirin ve User DSN sekmesini seçin (DSN=Veri Kaynağı Adı)

Image

  • Add düğmesiyle bir kaynak ekleyin, bu kaynağa Access sürücüsü aracılığıyla erişilebileceğini belirtin ve Terminer'i yapın:

Image

  • Veri kaynağına articles-access adını verin, istediğiniz bir açıklama girin ve Sélectionner düğmesini kullanarak veritabanındaki .mdb dosyasını belirtin. Son olarak OK ile bitirin.

Image

Böylece yeni veri kaynağı, DSN kullanıcı kaynakları listesinde görünür:

Image

MySQL DBARTICLES veritabanını ODBC veri kaynağı olarak tanımlamak için aşağıdaki adımları izleyin:

  • Yukarıda gösterildiği gibi ODBC veri kaynağı yöneticisini etkinleştirin ve DSN Kullanıcı sekmesini seçin. Add ile yeni bir veri kaynağı ekleyin ve MySQL'ten ODBC sürücüsünü seçin.

Image

  • Terminer'i seçin. Ardından, MySQL kaynağının yapılandırma sayfası görüntülenir:

54321

Image

  • (1) numaralı alanda veri kaynağımıza bir ad verin: ODBC
  • (2) numaralı alanda, MySQL sunucusunun bulunduğu makineyi belirtin. Burada, sunucunun uygulamamızla aynı makinede olduğunu belirtmek için localhost yazıyoruz. MySQL sunucusu uzak bir M makinesinde olsaydı, buraya o makinenin adını yazardık ve uygulamamız herhangi bir değişiklik yapılmasına gerek kalmadan uzak bir veritabanıyla çalışırdı.
  • (3) numaralı alana veritabanının adını giriyoruz. Burada veritabanının adı DBARTICLES'tir.
  • (4) numaralı alana admarticles kullanıcı adını, (5) numaralı alana ise mdparticles şifresini girin.

7.3.2. ODBC sürücüsünün kullanımı

Bağlantılı modda bir veritabanı kullanan bir uygulamada genellikle aşağıdaki adımlar izlenir:

  1. Veritabanına bağlanma
  2. Veritabanına SQL sorgularının gönderilmesi
  3. Bu sorguların sonuçlarının alınması ve işlenmesi
  4. Bağlantının kapatılması
  1. ve 3. adımlar tekrar tekrar gerçekleştirilir; bağlantı kapatma işlemi ise veritabanının kullanımı sona erdiğinde gerçekleşir. Bu, etkileşimli bir şekilde veritabanı kullanmışsanız aşina olabileceğiniz nispeten klasik bir şemadır. Veritabanı ister ODBC sürücüsü ister OLE veya DB sürücüsü aracılığıyla kullanılsın, bu adımlar aynıdır. Aşağıda, ODBC veri kaynaklarını yönetmeye yarayan .NET sınıflarını içeren bir örnek sunuyoruz. Programın adı liste'tir ve DSN adındaki, ODBC adlı bir veri kaynağına ait ARTICLES tablosunu parametre olarak kabul eder. Ardından bu tablonun içeriğini görüntüler:
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

Yukarıdaki sonuçlardan, programın hem ACCESS hem de MySQL veritabanlarının içeriğini listelediğini görüyoruz. Şimdi bu programın kodunu inceleyelim:


' seçenekler
Option Explicit On 
Option Strict On

' ad alanları
Imports System
Imports System.Data
Imports Microsoft.Data.Odbc
Imports Microsoft.VisualBasic

Module db1
    Sub main(ByVal args As String())
        ' konsol uygulaması
        ' DSN veritabanındaki ARTICLES tablosunun içeriğini görüntüler 
        ' adı parametre olarak geçirilen
        Const syntaxe As String = "syntaxe : pg dsnArticles"
        Const tabArticles As String = "articles"        ' la table des articles

        ' parametrelerin doğrulanması
        ' 1 parametre var mı?
        If args.Length <> 1 Then
            ' hata mesajı
            Console.Error.WriteLine(syntaxe)
            ' son
            Environment.Exit(1)
        End If

        ' parametre alınır
        Dim dsnArticles As String = args(0)                ' la base DSN
        ' veritabanına bağlantı hazırlığı
        Dim articlesConn As OdbcConnection = Nothing        ' la connexion
        Dim myReader As OdbcDataReader = Nothing            ' le lecteur de données

        ' veritabanına erişilmeye çalışılıyor
        Try
            ' veritabanı bağlantı dizesi
            Dim connectString As String = "DSN=" + dsnArticles + ";"
            articlesConn = New OdbcConnection(connectString)
            articlesConn.Open()

            ' SQL komutunun yürütülmesi
            Dim sqlText As String = "select * from " + tabArticles
            Dim myOdbcCommand As New OdbcCommand(sqlText)
            myOdbcCommand.Connection = articlesConn
            myReader = myOdbcCommand.ExecuteReader()

            ' Alınan tablonun işlenmesi
            ' sütunların görüntülenmesi
            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))

            ' verilerin görüntülenmesi
            While myReader.Read()
                ' Geçerli satırın işlenmesi
                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
            ' okuyucuyu kapatma
            myReader.Close()
            ' bağlantıyı kapatma
            articlesConn.Close()
        End Try
    End Sub
End Module

ODBC kaynak yönetim sınıfları, Microsoft.Data.Odbc ad alanında bulunur; bu nedenle bu ad alanı içe aktarılmalıdır. Ayrıca, bazı sınıflar System.Data ad alanında yer almaktadır.


Imports System.Data
Imports Microsoft.Data.Odbc

Program tarafından kullanılan ad alanları farklı derlemelerde yer almaktadır. Program, aşağıdaki komutla derlenir:

dos>vbc /r:microsoft.data.odbc.dll /r:microsoft.visualbasic.dll /r:system.dll /r:system.data.dll db1.vb

7.3.2.1. Bağlantı aşaması

ODBC bağlantısı, OdbcConnection sınıfını kullanır. Bu sınıfın oluşturucusu, parametre olarak “bağlantı dizesi” olarak adlandırılan bir değeri kabul eder. Bu, veritabanına bağlantı kurulabilmesi için gerekli tüm parametreleri tanımlayan bir karakter dizisidir. Bu parametrelerin sayısı çok fazla olabileceğinden, dize karmaşık bir yapıya sahip olabilir. Dize, "param1=valeur1;param2=valeur2;...;paramj=valeurj;" biçimindedir. İşte bazı olası paramj parametreleri:

uid
veritabanına erişecek bir kullanıcının adı
password
bu kullanıcının şifresi
dsn
Varsa veritabanının adı: DSN
data source
erişilen veritabanının adı
...
 

ODBC veri kaynağı yöneticisi kullanılarak bir veri kaynağı ODBC olarak tanımlanırsa, bu parametreler zaten girilmiş ve kaydedilmiş olur. Bu durumda, veri kaynağının adını DSN olarak veren DSN parametresini aktarmak yeterlidir. Burada yapılan da budur:


         ' veritabanına bağlantı hazırlığı
        Dim articlesConn As OdbcConnection = Nothing        ' la connexion
        Dim myReader As OdbcDataReader = Nothing        ' le lecteur de données
        Try
             ' veritabanına erişilmeye çalışılıyor
             ' veritabanı bağlantı dizesi
            Dim connectString As String = "DSN=" + dsnArticles + ";"
            articlesConn = New OdbcConnection(connectString)
            articlesConn.Open()

OdbcConnection nesnesi oluşturulduktan sonra, Open yöntemi ile bağlantı açılır. Bu bağlantı açma işlemi, veritabanındaki diğer tüm işlemler gibi başarısız olabilir. Bu nedenle, veritabanına erişim kodunun tamamı bir try-catch içinde yer almaktadır. Bağlantı kurulduktan sonra, veritabanına SQL sorguları gönderilebilir.

7.3.2.2. SQL sorguları göndermek

SQL sorguları göndermek için bir Command nesnesine ihtiyacımız var; burada daha doğrusu bir OdbcCommand nesnesine ihtiyacımız var, çünkü bir ODBC veri kaynağı kullanıyoruz. OdbcCommand sınıfının birkaç oluşturucusu vardır:

  • OdbcCommand(): Boş bir Command nesnesi oluşturur. Bunu kullanmak için daha sonra çeşitli özellikleri belirtmek gerekecektir:
    • CommandText: çalıştırılacak SQL sorgusunun metni
    • Bağlantı: Sorgunun yapılacağı veritabanına bağlantıyı temsil eden OdbcConnection nesnesi
    • CommandType: SQL sorgusunun türü. Üç olası değer vardır
  1. CommandType.Text: CommandText özelliği, bir SQL sorgusunun metnini içerir (varsayılan değer)
  2. CommandType.StoredProcedure: CommandText özelliği, veritabanında depolanmış bir saklı yordamın adını içerir
  3. CommandType.TableDirect: CommandText özelliği, T tablosunun adını içerir. select * from T ifadesine eşdeğerdir. Yalnızca OLE ve DB sürücüleri için geçerlidir.
  • OdbcCommand(string sqlText): sqlText parametresi, CommandText özelliğine atanacaktır. Bu, çalıştırılacak SQL sorgusunun metnidir. Bağlantı, Connection özelliğinde belirtilmelidir.
  • OdbcCommand(string sqlText, OdbcConnection bağlantı) : sqlText parametresi CommandText özelliğine, connexion parametresi ise Connection özelliğine atanacaktır.

SQL isteğini göndermek için iki yöntem mevcuttur:

  • OdbcdataReader ExecuteReader(): CommandText sorgusundan SELECT sorgusunu Connection bağlantısına gönderir veselect sorgusunun sonuç tablosundaki tüm satırlara erişim sağlar
  • int ExecuteNOnQuery() : güncelleme isteğini gönderir (INSERT, UPDATE, DELETE) CommandText'ten Connection bağlantısına gönderir ve bu güncellemeden etkilenen satır sayısını döndürür.

Örneğimizde, veritabanı bağlantısını açtıktan sonra, SQL SELECT sorgusunu göndererek ARTICLES tablosunun içeriğini alıyoruz:


             ' SQL komutunun yürütülmesi
            Dim sqlText As String = "select * from " + tabArticles
            Dim myOdbcCommand As New OdbcCommand(sqlText)
            myOdbcCommand.Connection = articlesConn
            myReader = myOdbcCommand.ExecuteReader()

Bir sorgu isteği genellikle şu türdedir:


    select col1, col2,... from table1, table2,...
    where condition
    order by expression
    ...

Yalnızca ilk satırdaki anahtar kelimeler zorunludur, diğerleri isteğe bağlıdır. Burada gösterilmeyen başka anahtar kelimeler de mevcuttur.

  1. "from" anahtar sözcüğünün ardından gelen tüm tablolarla birleştirme yapılır
  2. Yalnızca "select" anahtar sözcüğünün ardından gelen sütunlar tutulur
  3. Yalnızca "where" anahtar sözcüğündeki koşulu karşılayan satırlar tutulur
  4. "order by" anahtar sözcüğündeki ifadeye göre sıralanan satırlar, sorgunun sonucunu oluşturur.

select sorgusunun sonucu bir tablodur. Önceki ARTICLES tablosunu ele alırsak ve mevcut stoğu minimum eşik değerinin altında olan ürünlerin adlarını almak istersek, şu şekilde yazacağız:


    select nom from articles where stock_actuel<stock_minimum

Ürün adlarını alfabetik sırayla almak istersek, şunu yazacağız:


    select nom from articles where stock_actuel<stock_minimum order by nom

7.3.2.3. SELECT sorgusunun sonucunun değerlendirilmesi

Çevrimdışı modda SELECT sorgusunun sonucu bir DataReader nesnesidir; burada ise bir OdbcDataReader nesnesi. Bu nesne, sonucun tüm satırlarını sırayla almayı ve bu sonuçların sütunları hakkında bilgi edinmeyi sağlar. Bu sınıfın bazı özelliklerini ve yöntemlerini inceleyelim:

FieldCount
tablodaki sütun sayısı
Item
Item(i), sonucun geçerli satırındaki i numaralı sütunu temsil eder
XXX GetXXX(i)
geçerli satırın i numaralı sütununun değeri, XXX türü olarak döndürülür (Int16, Int32, Int64, Double, String, Boolean, ...)
string GetName(i)
i numaralı sütunun adı
Close()
OdbcdataReader nesnesini kapatır ve ilgili kaynakları serbest bırakır
bool Read()
sonuç tablosunda bir satır ilerler. Bu mümkün değilse false değerini döndürür. Yeni satır, okuyucunun geçerli satırı olur.

select sonucunun işlenmesi, genellikle metin dosyalarındakine benzer şekilde sıralı bir işlemdir: tabloda sadece ileriye doğru ilerlenebilir, geriye dönülmez:


While myReader.Read()
    ' bir satır var - bu satır işleniyor
    ....
     ' sonraki satır
end while

Bu açıklamalar, örneğimizdeki aşağıdaki kodu anlamak için yeterlidir:


            ' Alınan tablonun işlenmesi
            ' sütunların görüntülenmesi
            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))

            ' verilerin görüntülenmesi
            While myReader.Read()
                ' geçerli satırın işlenmesi
                ligne = ""
                For i = 0 To myReader.FieldCount - 1
                    ligne += myReader(i).ToString + " "
                Next i
                Console.WriteLine(ligne)
            End While

Tek zorluk, geçerli satırdaki farklı sütunların değerlerinin birleştirildiği komutta yatmaktadır:


                For i = 0 To myReader.FieldCount - 1
                    ligne += myReader(i).ToString + " "
                Next i

satır+=myReader(i).ToString notasyonu, satır+=myReader.Item(i).ToString() burada Item(i), geçerli satırın i numaralı sütunundaki değerdir.

7.3.2.4. Kaynakların Serbest Bırakılması

OdbcReader ve OdbcConnection sınıflarının her ikisi de, kapatılan nesnelerle ilişkili kaynakları serbest bırakan bir Close() yöntemine sahiptir.

                 ' okuyucuyu kapatma
                myReader.Close()
                 ' bağlantıyı kapatma
                articlesConn.Close()

7.3.3. OLE sürücüsünün kullanımı DB

Aynı örneği tekrar ele alıyoruz, ancak bu sefer bir sürücü aracılığıyla erişilen bir veritabanı kullanıyoruz: OLE DB. .NET platformu, ACCESS veritabanları için bu tür bir sürücü sağlar. Bu nedenle, daha önce kullandığımız articles.mdb veritabanını kullanacağız. Burada, sınıflar değişse de kavramların aynı kaldığını göstermeyi amaçlıyoruz:

  • Bağlantı, OleDbConnection nesnesiyle temsil edilmektedir
  • OleDbCommand nesnesi aracılığıyla bir SQL sorgusu gönderilir
  • bu sorgu bir SELECT cümlesi ise, sonuç tablosundaki satırlara erişmek için karşılık olarak bir OleDbDataReader nesnesi elde edilir

Bu sınıflar System.Data.OleDb ad alanında yer alır. Yukarıdaki program, bir OLE DB veritabanını yönetmek üzere kolayca dönüştürülebilir:

  • her yerde OdbcXX yerine OleDbXX yazılır
  • bağlantı dizesi değiştirilir. Kullanıcı adı/şifre gerektirmeyen bir ACCESS veritabanı için bağlantı dizesi Provider=Microsoft.JET.OLEDB.4.0;Data Source=[fichier.mdb] şeklindedir. Bu dizgenin ayarlanabilir kısmı, kullanılacak ACCESS dosyasının adıdır. Programımızı, bu dosyanın adını parametre olarak kabul edecek şekilde değiştireceğiz.
  • İçe aktarılacak ad alanı artık System.Data.OleDb'tir.

Programımız şu şekilde olur:


' seçenekler
Option Explicit On 
Option Strict On

' ad alanları
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)

        ' konsol uygulaması
        ' DSN veritabanındaki ARRTICLES tablosunun içeriğini görüntüler 
        ' adı parametre olarak geçirilen
        Const syntaxe As String = "syntaxe : pg base_access_articles"
        Const tabArticles As String = "articles"        ' la table des articles

        ' parametrelerin doğrulanması
        ' 1 parametre var mı?
        If args.Length <> 1 Then
            ' hata mesajı
            Console.Error.WriteLine(syntaxe)
            ' son
            Environment.Exit(1)
        End If

        ' parametre alınır
        Dim dbArticles As String = args(0)        ' la base de données

        ' veritabanına bağlantı hazırlığı
        Dim articlesConn As OleDbConnection = Nothing        ' la connexion
        Dim myReader As OleDbDataReader = Nothing        ' le lecteur de données

        ' veritabanına erişilmeye çalışılıyor

        Try
            ' veritabanı bağlantı dizesi
            Dim connectString As String = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=" + dbArticles + ";"
            articlesConn = New OleDbConnection(connectString)
            articlesConn.Open()

            ' SQL komutunun yürütülmesi
            Dim sqlText As String = "select * from " + tabArticles
            Dim myOleDbCommand As New OleDbCommand(sqlText)
            myOleDbCommand.Connection = articlesConn
            myReader = myOleDbCommand.ExecuteReader()

            ' Alınan tablonun işlenmesi
            ' sütunların görüntülenmesi
            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))
            ' verilerin görüntülenmesi
            While myReader.Read()
                ' Geçerli satırın işlenmesi
                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
            ' okuyucuyu kapatma
                myReader.Close()
                ' bağlantıyı kapatma
                articlesConn.Close()
        End Try
        ' son
        Environment.Exit(0)
    End Sub
End Module

Elde edilen sonuçlar:

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. Bir tablonun güncellenmesi

Önceki örneklerde sadece bir tablonun içeriği listelenmişti. Ürün veritabanını yönetme programımızı, veritabanında değişiklik yapabilmesi için düzenliyoruz. Programın adı sql'tir. Programa, yönetilecek ürün veritabanının adı olan DSN parametre olarak verilir. Kullanıcı, SQL komutlarını klavyeden doğrudan girer ve program bunları yürütür; aşağıda, MySQL ürün veritabanında elde edilen sonuçlar gösterilmektedir:

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

Program şu şekildedir:


' seçenekler
Option Explicit On 
Option Strict On

' ad alanları
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)

        ' konsol uygulaması
        ' klavyeyle girilen SQL sorgularını bir 
        ' adının parametre olarak geçirildiği bir veritabanındaki ARTICLES tablosunda
        Const syntaxe As String = "syntaxe : pg dsnArticles"

        ' parametrelerin doğrulanması
        ' 2 parametre var mı
        If args.Length <> 1 Then
            ' hata mesajı
            Console.Error.WriteLine(syntaxe)
            ' son
            Environment.Exit(1)
        End If        'if
        ' parametre alınır
        Dim dsnArticles As String = args(0)
        ' veritabanına bağlantı dizesi
        Dim connectString As String = "DSN=" + dsnArticles + ";"

        ' veritabanına bağlantı hazırlığı
        Dim articlesConn As OdbcConnection = Nothing
        Dim sqlCommand As OdbcCommand = Nothing
        Try
            ' veritabanına erişilmeye çalışılıyor
            articlesConn = New OdbcConnection(connectString)
            articlesConn.Open()
            ' bir command nesnesi oluşturuluyor
            sqlCommand = New OdbcCommand("", articlesConn)
            'try
        Catch ex As Exception
            ' hata mesajı
            Console.Error.WriteLine(("Erreur d'exploitation de la base de données (" + ex.Message + ")"))
            ' kaynakların serbest bırakılması
            Try
                articlesConn.Close()
            Catch
            End Try
            Environment.Exit(2)
        End Try        'catch
        ' kabul edilen SQL komutlarının sözlüğü oluşturuluyor
        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

        ' klavyeden girilen komutların okunması ve yürütülmesi 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+")
        ' klavyeden girilen SQL komutlarının girilme-yürütülme döngüsü
        While True
            ' başlangıçta hata yok
            Dim erreur As Boolean = False
            ' istek talebi
            Console.Out.Write(ControlChars.Lf + "Requête SQL (fin pour arrêter) : ")
            requête = Console.In.ReadLine().Trim().ToLower()
            ' bitti mi?
            If requête = "fin" Then
                Exit While
            End If
            ' isteği alanlara ayrıştırıyoruz
            champs = modèle.Split(requête)
            ' istek geçerli mi?
            If champs.Length = 0 Or Not dicoCommandes.ContainsKey(champs(0)) Then
                ' hata mesajı
                Console.Error.WriteLine("Requête invalide. Utilisez select, insert, update, delete")
                ' sonraki istek
                erreur = True
            End If
            If Not erreur Then
                ' isteği yürütmek için Command nesnesinin hazırlanması
                sqlCommand.CommandText = requête
                ' isteğin yürütülmesi
                Try
                    If champs(0) = "select" Then
                        executeSelect(sqlCommand)
                    Else
                        executeUpdate(sqlCommand)
                    End If
                Catch ex As Exception
                    ' hata mesajı
                    Console.Error.WriteLine(("Erreur d'exploitation de la base de données (" + ex.Message + ")"))
                End Try
            End If
        End While
        ' kaynakların serbest bırakılması
        Try
            articlesConn.Close()
        Catch
        End Try
        Environment.Exit(0)
    End Sub

    ' güncelleme sorgusunun yürütülmesi
    Sub executeUpdate(ByVal sqlCommand As OdbcCommand)
        ' sqlCommand güncelleme isteğini yürütür
        Dim nbLignes As Integer = sqlCommand.ExecuteNonQuery()
        ' görüntüleme
        Console.Out.WriteLine(("Il y a eu " & nbLignes & " ligne(s) modifiée(s)"))
    End Sub

    ' Select sorgusunun yürütülmesi
    Sub executeSelect(ByVal sqlCommand As OdbcCommand)
        ' sqlCommand'i yürütür, Select sorgusu
        Dim myReader As OdbcDataReader = sqlCommand.ExecuteReader()
        ' Alınan tablonun işlenmesi
        ' sütunların görüntülenmesi
        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))
        ' Verilerin görüntülenmesi
        While myReader.Read()
            ' Geçerli satırın işlenmesi
            ligne = ""
            For i = 0 To myReader.FieldCount - 1
                ligne += myReader(i).ToString + " "
            Next i
            ' Görüntüleme
            Console.WriteLine(ligne)
        End While
        ' Kaynakların serbest bırakılması
        myReader.Close()
    End Sub
End Module

Burada, önceki programa göre yeni olan hususlara değineceğiz:

  • Kabul edilen SQL komutlarının bir sözlüğünü oluşturuyoruz:

         ' kabul edilen SQL komutlarının sözlüğü oluşturuluyor
        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

Bu sayede, girilen sorgunun ilk kelimesinin (champs[0]) kabul edilen dört komuttan biri olup olmadığını kolayca kontrol edebiliriz:


             ' sorgu geçerli mi?
            If champs.Length = 0 Or Not dicoCommandes.ContainsKey(champs(0)) Then
                ' hata mesajı
                Console.Error.WriteLine("Requête invalide. Utilisez select, insert, update, delete")
                 ' sonraki sorgu
                erreur = True
            End If            'if
  • Daha önce sorgu, RegEx sınıfının Split yöntemi kullanılarak alanlara ayrılmıştı:

        Dim modèle As New Regex("\s+")
....
            ' sorguyu alanlara ayrıştırma
            champs = modèle.Split(requête)

Sorguyu oluşturan kelimeler, aralarında istediğiniz sayıda boşluk bırakılarak ayrılabilir.

  • select sorgusunun yürütülmesi, bir güncelleme sorgusunun (insert, update, delete) yürütülmesiyle aynı yöntemi kullanmaz. Bu nedenle, bir test yapmalı ve bu iki durumun her biri için farklı bir işlev çalıştırmalısınız:

                 ' Sorguyu yürütmek için Command nesnesinin hazırlanması
                sqlCommand.CommandText = requête
                 ' sorgunun yürütülmesi
                Try
                    If champs(0) = "select" Then
                        executeSelect(sqlCommand)
                    Else
                        executeUpdate(sqlCommand)
                    End If                    'try
                Catch ex As Exception
                    ' hata mesajı
                    Console.Error.WriteLine(("Erreur d'exploitation de la base de données (" + ex.Message + ")"))
                End Try

SQL sorgusunun yürütülmesi, burada işlenen bir istisna oluşturabilir.

  • executeSelect işlevi, önceki örneklerde görülen tüm unsurları içermektedir.
  • executeUpdate işlevi, OdbcCommand sınıfındaki ExecuteNonQuery yöntemini kullanır; bu yöntem, komutun etkilediği satır sayısını döndürür.

7.3.5. IMPOTS

Bir önceki bölümde oluşturduğumuz impôt nesnesini tekrar ele alıyoruz:


' seçenekler
Option Strict On
Option Explicit On 

' ad alanları
Imports System

Public Class impôt
    ' vergi hesaplaması için gerekli veriler
    ' harici bir kaynaktan geliyor
    Private limites(), coeffR(), coeffN() As Decimal

    ' üretici
    Public Sub New(ByVal LIMITES() As Decimal, ByVal COEFFR() As Decimal, ByVal COEFFN() As Decimal)
        ' 3 tablonun da aynı boyutta olup olmadığı kontrol edilir
        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
        ' sorun yok
        Me.limites = LIMITES
        Me.coeffR = COEFFR
        Me.coeffN = COEFFN
    End Sub

    ' vergi hesaplaması
    Public Function calculer(ByVal marié As Boolean, ByVal nbEnfants As Integer, ByVal salaire As Integer) As Long
        ' pay sayısının hesaplanması
        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
        ' vergilendirilebilir gelir ve aile katsayısı hesaplaması
        Dim revenu As Decimal = 0.72D * salaire
        Dim QF As Decimal = revenu / nbParts
        ' vergi hesaplaması
        limites((limites.Length - 1)) = QF + 1
        Dim i As Integer = 0
        While QF > limites(i)
            i += 1
        End While
        ' sonuçun döndürülmesi
        Return CLng(revenu * coeffR(i) - nbParts * coeffN(i))
    End Function
End Class

Buna, limites, coeffR ve coeffN tablolarını ODBC veritabanından başlatmaya yarayan yeni bir oluşturucu ekliyoruz:


Imports System.Data
Imports Microsoft.Data.Odbc
Imports System.Collections
...


    ' oluşturucu 2
    Public Sub New(ByVal DSNimpots As String, ByVal Timpots As String, ByVal colLimites As String, ByVal colCoeffR As String, ByVal colCoeffN As String)
        ' QZXW2HTMLCTORCQwZQX veritabanındaki Timpots tablosunun içeriğinden
        ' ODBC veritabanındaki Timpots tablosunun içeriğinden DSNimpots
        ' colLimites, colCoeffR, colCoeffN bu tablonun üç sütunudur
        ' bir istisna oluşturabilir
        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
        ' SELECT sorgusu
        Dim selectCommand As String = "select " + colLimites + "," + colCoeffR + "," + colCoeffN + " from " + Timpots
        ' verileri almak için tablolar
        Dim tLimites As New ArrayList
        Dim tCoeffR As New ArrayList
        Dim tCoeffN As New ArrayList

        ' veritabanına erişilmeye çalışılır
        impotsConn = New OdbcConnection(connectString)
        impotsConn.Open()
        ' bir komut nesnesi oluşturuluyor
        sqlCommand = New OdbcCommand(selectCommand, impotsConn)
        ' sorgu yürütülüyor
        Dim myReader As OdbcDataReader = sqlCommand.ExecuteReader()
        ' Alınan tablonun işlenmesi
        While myReader.Read()
            ' geçerli satırın verileri tablolara aktarılıyor
            tLimites.Add(myReader(colLimites))
            tCoeffR.Add(myReader(colCoeffR))
            tCoeffN.Add(myReader(colCoeffN))
        End While
        ' Kaynaklar serbest bırakılır
        myReader.Close()
        impotsConn.Close()

        ' Dinamik tablolar statik tablolara aktarılır
        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

Test programı şu şekildedir: impôt sınıfının oluşturucusuna iletilecek parametreleri argüman olarak alır. Bir impôt nesnesi oluşturduktan sonra, ödenecek vergi hesaplamalarını yapar:


Option Explicit On 
Option Strict On

' ad alanları
Imports System
Imports Microsoft.VisualBasic

' test sayfası
Module testimpots
    Sub Main(ByVal arguments() As String)
        ' etkileşimli vergi hesaplama programı
        ' kullanıcı klavyeden üç veri girer: evli nbEnfants maaş
        ' program daha sonra ödenecek vergiyi gösterir
        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"

        ' program parametrelerinin kontrolü
        If arguments.Length <> 5 Then
            ' hata mesajı
            Console.Error.WriteLine(syntaxe1)
            ' son
            Environment.Exit(1)
        End If        'if
        ' argümanlar alınır
        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)

        ' vergi nesnesi oluşturuluyor
        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

        ' sonsuz döngü
        While True
            ' başlangıçta hata yok
            Dim erreur As Boolean = False

            ' vergi hesaplaması için parametreler isteniyor
            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()

            ' ne yapılmalı?
            If paramètres Is Nothing Or paramètres = "" Then
                Exit While
            End If

            ' giriş satırındaki argüman sayısının kontrolü
            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
                ' parametrelerin geçerliliğinin kontrolü
                ' evli
                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
                ' maaş
                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
                ' parametreler doğru - vergi hesaplanıyor
                Console.Out.WriteLine(("impôt=" & objImpôt.calculer(marié = "o", nbEnfants, salaire).ToString + " F"))
            End If
        End While
    End Sub
End Module

Kullanılan veritabanı, adı DSN mysql-impots olan bir MySQL veritabanıdır:

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 |
+---------+--------+---------+

Test programının çalıştırılması sonucunda aşağıdaki sonuçlar elde edilir:

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 :