Visual BasicでMicrosoft SQL Serverを操作する

AccessからSQL Serverへのスキルのアップサイズ

−Microsoft SQL Server入門講座:2−

秋月巌 AKIZUKI, Iwao



●SQL Serverを使いこなすためのツールとは



★Microsoft SQL ServerはNTサービスとして動作する

 最近のソフトウェアパッケージのほとんどすべては、複数のプログラムによって構成されている。だから、インストール時に作成されるプログラムフォルダには、多数のアイコンが登録されることになる。Microsoft SQL Serverも例外ではない。READMEファイルやヘルプファイルを別にしても、10個近いプログラムアイコンが登録される。
 しかし、登録されたアイコンの中に、Microsoft SQL Server本体のアイコンはない。Microsoft SQL Serverはインストール時にWindows NTのサービスとして組み込まれ、デフォルトでは自動的に起動するように設定される。つまり、インストール後、再起動した時点ですでにMicrosoft SQL Serverは起動しているのである。サービスとして起動しているアプリケーションはタスクバーに登録されないため、Microsoft SQL Serverが起動しているかどうかは、Windows NTのデスクトップから判断することはできない。
 起動しているMicrosoft SQL Serverを停止したり再起動するには、SQL Serviceマネージャを使用する。あるいは、SQL Enterpriseマネージャを使用してもいい。SQL EnterpriseマネージャはMicrosoft SQL Serverを操作するための万能ツールだが、これらはあくまでも、Microsoft SQL Serverの管理ツールであって、Microsoft SQL Server自体ではない。

★データベースエンジンと管理ツール

 ここまでの話をMicrosoft Accessに置き換えると、もっとややこしくなる。Microsoft AccessをRDBMSとしてとらえるならば、データベース本体はJetデータベースエンジンだということになる。Jetデータベースエンジンがロードされているかどうかを、デスクトップから判断することはできない。起動してデスクトップに表示されているMicrosoft Accessは、Jetデータベースエンジンの管理ツールなのだということもできる。もっとも、話はそんなにシンプルではない。Microsoft Accessはあくまでも、Jetデータベースエンジンを含んだ製品名だからである。
 それに実際のMicrosoft Accessは、データベースエンジンの管理ツールという以上の能力をもっている。たとえば、非常に高いレベルのデータ編集機能があげられる。このためJetデータベースエンジンに格納されているデータを操作する場合、SQLを記述する必要はない。一方、Microsoft SQL Serverに標準で付属するツールを使ってデータを操作する場合、ISQLツールを使う必要がある。このツールを使ってデータを操作するにはSQLを記述しなければならない。そのようなことからMicrosoft SQL Serverのデータを確認したり、操作するためにMicrosoft Accessのテーブルのリンク機能を使っている方も多いだろう。
 さらにMicrosoft Accessの強力な長所としてあげられるのは、プログラミング開発能力である。他方、Microsoft SQL Serverというパッケージは、データベースサービスを行なうことが目的であるため、アプリケーションを開発するための機能は提供されない。随一の例外が先月号で紹介したWebアシスタントということになる。
 もちろん、これはMicrosoft AccessとMicrosoft SQL Server単体を比較した場合の違いであって、しかるべきツールを組み合わせて使用してこそ、Microsoft SQL Serverは強力なサービスを提供するのである。しかるべきツールとは、Visual Basicである。Microsoft SQL Serverは、決して単体で使用する製品ではない。



●RDO? SQL-DMO?


★Microsoft SQL Serverの管理ツール

 Visual Basic Enterprise Editionには、Visual Database Toolsというデータマネージメントのためのツールが付属している(図1)。このツールはODBCを経由してMicrosoft SQL Serverのデータの操作をビジュアルに行なえるほか、SQL文の生成機能も備えている。その他、テーブルやストアドプロシージャの作成も可能であり、概してSQL Enterpriseマネージャよりも使い勝手がよい。しかし、やはり、開発ツールの付属ツールであるため、データベースとプログラムのプロジェクトを関連づける必要があるし、データベースの管理機能もあくまでも開発者用に制限されている。


図1:Visual BasicのVisual Database Tools
699*566


★管理作業をプログラミング可能にするSQL-DMO

 そこで、プログラマがMicrosoft SQL Serverを自在に扱うために用意されているのが、SQL-DMOである。SQL-DMOは、それ自体がツールだというわけではない。Microsoft SQL Server自体をオブジェクトとしてパッケージし、機能を公開しているAPIである。
 APIだから、当然、操作するためにはプログラミングが必要になる。逆にいえば、プログラミングすればかなり柔軟な操作が可能になるということである。SQL Enterpriseマネージャが、SQL-DMOを利用して作られていることを考えれば、SQL-DMOが公開している機能がどれほど強力かわかるだろう。


★RDOとSQL-DMOの目的の違い

 Visual BasicによるMicrosoft SQL Serverのプログラムというと、RDOの利用が一般的だが、RDOとSQL-DMOとでは作成するプログラムの目的が異なる。SQL文を利用してMicrosoft SQL Serverがハンドリングするデータを操作するのが、RDOを使用したプログラミングのターゲットなのに対して、SQL-DMOはMicrosoft SQL Server自体を操作することを目的としている。SQL-DMOはSQL文を実行することもできるので、データを操作するプログラムを作成することは可能だが、取得したレコードセットを操作する能力などから考えて、データの操作だけに機能が限定されるなら、RDOを使用すべきである。
 たとえば、SQL-DMOを利用すると、次のような操作をVisual Basicプログラムから行なうことができるようになる。以下であげる操作の多くが、SQL Enterpriseマネージャの機能と共通であることがわかるだろう。

SQL Serverの起動、シャットダウン テーブルとインデックスの一貫性の確認 テーブルのチェック制約情報の取得
オプション設定値の取得と設定 データベースのバックアップと復元 テーブルのチェック制約の作成と削除
デバイス情報の取得 データベースサイズの拡大と縮小 列プロパティの設定と取得
デバイスやミラーデバイスの作成、削除 バックアップスクリプトの生成 インデックス情報の取得
データベース情報の取得 メモリー使用状況の取得 インデックスの作成と削除
言語情報の取得と設定 データベースの領域情報の取得 キー情報の取得
ユーザー情報の取得と設定 データベースの作成と削除 キーの作成と削除
リモートサーバーの情報取得 データベースの主キーリストの取得 テーブル情報の取得と設定
SQL文の実行 デバイス一覧の取得 テーブルの作成、削除、変更
レプリケーションの設定、変更、実行 ルールやデフォルトの作成とバインド テーブルのデバイス使用状況の参照
トランザクションの指定 ユーザーやグループの作成と削除 トリガ情報の取得と設定
エラーログの参照 ストアドプロシージャの情報の取得と設定 トリガの作成と削除
ロック情報の取得 ストアドプロシージャの作成と削除 警告に関する情報の取得
バージョン情報の取得 トランザクションログの参照と削除 タスクスケジューリング情報の取得と設定
システムテーブルの確認 トランザクションログ情報の取得 タスクスケジューリングの実行
チェックポイントの実行 トランザクションログのバックアップ 起動時の設定の取得と変更




●SQL-DMOをVsual Basicで使う


★コンポーネントを組み込む
 SQL-DMOはCOMコンポーネントとして提供されるため、プログラミングに使用するには、まず初めにコンポーネントがローカルマシンにインストールされている必要がある。つまりローカルマシンにインストールされているコンポーネントを利用して、Microsoft SQL Serverを操作する形になる。たから、開発ツールとしてVisual Basicを使用する場合は[プロジェクト]メニューの[参照設定]で[Microsoft SQLOLE Object Library]を指定する(図2)。

★SQL-DMOのオブジェクトモデル

 コンポーネントとして提供されるオブジェクトを操作するときは、オブジェクトモデルを正しく理解しなければならない。SQL-DMOのオブジェクトモデルが、図3である。Applicationオブジェクトの下位にSQL Serverオブジェクトが位置づけられ、さらにその下位に各種のエレメントが存在する。各オブジェクトは対応するターゲットを表現しているので、ターゲットを操作する場合には、オブジェクトが所有するプロパティやメソッドを利用する。たとえば、データベースの作成日付が知りたい場合は、DatabaseオブジェクトのCreateDateプロパティを操作するという具合である。

図2:[プロジェクト]メニューの[参照設定]で[Microsoft SQLOLE Object Library]を指定
459*310
図3:SQL-DMOのオブジェクトモデル
489*480
 この中でよく使われるのは、Applicationオブジェクト、SQLServerオブジェクト、それにデータベースオブジェクトだろう。ApplicationオブジェクトはSQL-DMO自体を表現している。また、図3では省略されているが、下位にBackupオブジェクトや、QueryResultオブジェクトを所有している。QueryResultオブジェクトは、Transact SQLを実行した場合の結果を格納するオブジェクトである。SELECT文を実行した場合の結果セットも、このオブジェクトに格納される。
 SQLServerオブジェクトは、接続された任意のデータベースを表現する。接続したデータベースの情報を保持するほか、下位オブジェクトを参照することで、そのデータベースを構成する要素を操作したり、状態情報を取得することが可能になる。たとえば、下位オブジェクトであるDatabaseオブジェクトのSpaceAvailableプロパティを利用して、データベースの空き容量を取得したり、ExtendOnDevices メソッドを使用して容量の拡張をすることもできる。


★SQL-DMOサンプル1:サーバーの情報を取得

 では、SQL-DMOを使用したプログラミングを実際のサンプルを用いて解説する。リスト1(図4)は、SQL-DMOを用いて、サーバー情報を取得するためのサンプルである。[ログインしてサーバーの情報を取得]ボタンをクリックしたときに実行されるイベントプロシージャがリスト1である。
 このプロシージャには、次のように一連の処理が記述されている。
  1. SQLserverオブジェクトのインスタンスを作成する
  2. ログインをして接続をする
  3. サーバーの情報を取得して表示
  4. ログオフをする

 SQLServerオブジェクトのインスタンスを作成しているのが、次の一行である。


   Dim SQLObj As New SQLOLE.SQLServer

 ここでは、SQLServerオブジェクトは宣言と同時に事前バインディングされている。この行以降、SQLServerオブジェクトは、SQLObjという名称において、参照することができる。
 次のコードは、SQLServerオブジェクトのConnectionメソッドを使用して、指定されたサーバーで稼動するMicrosoft SQL Serverに接続する。


  SQLObj.Connect Trim(txt_sqlsvr), _
    Trim(txt_user), Trim(txt_pass)


図4:サンプル1サーバーの情報を取得
419*424

Connectionメソッドの書式は次のとおりである。


  SQLServer.Connect (
      [[ServerName :=] strServer, ]
      [[Login :=] idLogin, ]
      [[Password :=] idPassword] )


 引数には、サーバー名、ユーザー名、パスワードが渡される。ログイン後は、ここで指定されたユーザーの権限の範囲においてSQLServerオブジェクトを操作することが可能である。サンプル1のコードでは、テキストボックスの内容を直接、Connectメソッドの引数として渡している。
 以下のコードは、SQLServerオブジェクトのプロパティを使って取得した情報を、ラベルコントロールに改行しながら表示している。


  With SQLObj
        lbl_info = .Name
        lbl_info = lbl_info & vbCrLf & _
          "SQL-DMO 接続 ID : " & .ConnectionID
        lbl_info = lbl_info & vbCrLf & _
          "クライアントマシン名 : " & .HostName

 ここでは、データの取得と表示しか行なっていないが、いくつかのプロパティは値の設定も可能である。

リスト1:サンプル1の全ソースコード(ログインしてサーバー情報を取得)


Private Sub Command1_Click()
    Dim SQLObj As New SQLOLE.SQLServer
    Dim PacketSize As Integer

    SQLObj.Connect Trim(txt_sqlsvr), Trim(txt_user), Trim(txt_pass)

    With SQLObj
        lbl_info = .Name
        lbl_info = lbl_info & vbCrLf & "SQL-DMO 接続 ID : " & .ConnectionID
        lbl_info = lbl_info & vbCrLf & "クライアントマシン名 : " & .HostName
        lbl_info = lbl_info & vbCrLf & "使用言語 : " & .Language
        lbl_info = lbl_info & vbCrLf & "数値型の精度 : " & _
          .MaxNumericPrecision
        PacketSize = .NetPacketSize
        If PacketSize = 0 Then
            PacketSize = 4096
        End If
        lbl_info = lbl_info & vbCrLf & "パケットサイズ : " & PacketSize
        lbl_info = lbl_info & vbCrLf & "プロセスID : " & .ProcessID
        lbl_info = lbl_info & vbCrLf & "クエリーのタイムアウト時間 : " & _
          .QueryTimeout
        lbl_info = lbl_info & vbCrLf & "バージョン情報 : " & .VersionString
        lbl_info = lbl_info & vbCrLf & "レジストリ情報 "
        With .Registry
            lbl_info = lbl_info & vbCrLf & "AutostartLicensing : " & _
              .AutostartLicensing
            lbl_info = lbl_info & vbCrLf & "AutostartMail : " & .AutostartMail
            lbl_info = lbl_info & vbCrLf & "AutostartServer : " & _
              .AutostartServer
            lbl_info = lbl_info & vbCrLf & "CaseSensitive : " & .CaseSensitive
            lbl_info = lbl_info & vbCrLf & "ErrorLogPath : " & .ErrorLogPath
            lbl_info = lbl_info & vbCrLf & "MasterDBPath : " & .MasterDBPath
            lbl_info = lbl_info & vbCrLf & "PhysicalMemory : " & _
              CStr(.PhysicalMemory)
            lbl_info = lbl_info & vbCrLf & "SortOrder : " & .SortOrder
        End With
    .DisConnect
    End With
End Sub



★SQL-DMOサンプル2:データベースの情報を取得

 リスト2では、データベースに関する情報を取得する方法を説明する。このサンプル(図5)は、フォーム上にある[ログインしてデータベース名を列挙]ボタンをクリックすると、テキストボックスに入力された情報を元に、Microsoft SQL Serverにログインし、リストボックスにデータベースの名前を列挙する。次にリストボックスからデータベースを選択すると、下部にあるラベルに指定されたデータベースの情報を表示する。
 SQLServerオブジェクトのDatabasesコレクションは、データベースサーバーが保有する複数のデータベースを表現する。以下のコードはコレクションを参照して、リストボックスにデータベースの名称を列挙している。

  For Each objDB In SQLObj.Databases
     lst_dbname.AddItem objDB.Name
  Next objDB

図5:サンプル2データベースの情報を取得
381*365

 データベース名を取得するのに使用しているのは、DatabaseオブジェクトのNameプロパティである。Forループにより、コレクションの数だけNameプロパティの値がリストボックスに追加される。
 リストボックスのClickイベントプロシージャに記述されているのが、次のコードである。


  With SQLObj.Databases(CStr(lst_dbname))
       lbl_dbinfo = "テーブル数 : " & .Tables.Count & vbCrLf
       lbl_dbinfo = lbl_dbinfo & "ビューの数 : " & .Views.Count & vbCrLf
       lbl_dbinfo = lbl_dbinfo & "作成日 : " & .CreateDate & vbCrLf
  End With

 Databaseコレクションのインデックスにデータベース名を指定して、情報を取得するデータベースを特定している。DatabaseオブジェクトはTablesコレクションを所有し、そのCountプロパティを取得することで、データベースに保存されているテーブルの総数が取得できる。Viewsコレクションの数も同様の方法で取得できる。
 データベースに関する情報で必要となる頻度が高いのが、領域に関する情報だろう。特に空き領域の値は管理情報として、神経質に管理する必要がある。データベースの領域が不足すれば、Microsoft SQL Serverは作業を継続することができないからである。
リスト2:サンプル2の全ソースコード(ログインしてデータベースの情報を取得)



Dim SQLObj As New SQLOLE.SQLServer

Private Sub Command1_Click()
    Dim objDB As SQLOLE.Database
    SQLObj.Connect Trim(txt_sqlsvr), Trim(txt_user), Trim(txt_pass)

    For Each objDB In SQLObj.Databases
       lst_dbname.AddItem objDB.Name
    Next objDB
End Sub

Private Sub lst_dbname_Click()
   With SQLObj.Databases(CStr(lst_dbname))
     lbl_dbinfo = "テーブル数 : " & .Tables.Count & vbCrLf
     lbl_dbinfo = lbl_dbinfo & "ビューの数 : " & .Views.Count & vbCrLf
     lbl_dbinfo = lbl_dbinfo & "作成日 : " & .CreateDate & vbCrLf
     lbl_dbinfo = lbl_dbinfo & "データ使用領域 : " & _
       CStr(.DataSpaceUsage) & vbCrLf
     lbl_dbinfo = lbl_dbinfo & "サイズ : " & CStr(.Size) & vbCrLf
     lbl_dbinfo = lbl_dbinfo & "空き容量 : " & _
       CStr(.SpaceAvailableInMB) & vbCrLf
     lbl_dbinfo = lbl_dbinfo & "バージョン : " & .Version & vbCrLf
   End With
End Sub


★SQL-DMOサンプル3:Transact SQLを実行

 SQL-DMOはMicrosoft SQL Serverを操作することを目的としたコンポーネントだが、SQL文を実行することもできる。リスト3はSQL-DMOを使ってSQL文を実行し、受け取った結果を表示するサンプル(図6)である。サンプル2と同様、このサンプルもログインに必要な情報を入力して[ログインしてデータベース名を列挙]ボタンをクリックすると、リストボックスにデータベース名が列挙される。その中からひとつを選択し、実行するSQL文を記述して[SQLの実行]ボタンをクリックすると、Microsoft SQL Serverが応答した結果がテキストボックスに表示される。
 結果セットのあるクエリーを実行するために、SQL-DMOではDatabasesコレクションのExecuteWithResultsメソッドを利用する。SQLを実行しているのが次の行である。


  Set rsQResult = SQLObj.Databases(CStr(lst_dbname)) _
    .ExecuteWithResults(txt_sqlstat)


 Databasesコレクションのインデックスにデータベース名を指定し、 ExecuteWithResultsメソッドの引数に実行するSQL文を渡している。クエリーの結果はQueryResultsオブジェクトに格納される。受け取ったSQLの結果を表示するのが、次のコードである。

  For rowNo = 1 To rsQResult.Rows
     For colNo = 1 To rsQResult.Columns
       txt_result = txt_result & rsQResult _
         .GetColumnString(rowNo, colNo) & ","
     Next colNo
     txt_result = txt_result & vbCrLf
   Next rowNo

 QueryResultsオブジェクトのRowsプロパティとColumnsプロパティは、それぞれ結果セットの行の数と列の数を取得できる。内容を取得するには、GetColumnStringメソッドを使用している。引数に行と列の番号を指定すれば、該当項目の値を取得することができる。必要な回数をループで回すことで、テーブルの内容がすべて出力される。

図6:Transact SQLを実行
383*486
リスト3:サンプル3の全コード(Transact SQLの実行)


Dim SQLObj As New SQLOLE.SQLServer
Private Sub cmd_execute_Click()
   Dim colNo, rowNo As Integer
   Dim rsQResult As SQLOLE.QueryResults
   Set rsQResult = SQLObj.Databases(CStr(lst_dbname)) _
     .ExecuteWithResults(txt_sqlstat)
   rowNo = 0
   For rowNo = 1 To rsQResult.Rows
     For colNo = 1 To rsQResult.Columns
       txt_result = txt_result & rsQResult.GetColumnString(rowNo, colNo) & ", "
     Next colNo
     txt_result = txt_result & vbCrLf
   Next rowNo
End Sub
Private Sub Command1_Click()
    Dim objDB As SQLOLE.Database
    SQLObj.Connect Trim(txt_sqlsvr), Trim(txt_user), Trim(txt_pass)

    For Each objDB In SQLObj.Databases
       lst_dbname.AddItem objDB.Name
    Next objDB
End Sub



●次回は…



 SQL-DMOを利用したプログラミングについて説明したが、今回はMicrosoft SQL Serverに関する情報や、データを取得する方法について説明した。次号ではデバイスやデータベースの管理など、Microsoft SQL Serverに対して、能動的に操作するプログラミング方法について解説する。


 なお、この連載で解説したサンプルアプリケーションは下記のURLからダウンロード可能である。
http://akizuki.adsp.or.jp/



VB Magazine ライブラリ | Visual Basic WorkGroup
int21 ホームページ | PCDN ホームページ


Copyright (c) 1998 PCDN All Rights Reserved.
For questions or comments, please send mail to: pcdn@int21.co.jp