すいません、VB4しかやってないんです、VBAはやったけど(ぼそ) チラシの裏だって立派な書き込み空間なんだからねっ!資源の有効活用なんだからねっ!とか偉そうに言ってるけど、実は色々と書き残したいだけ

だからなに? どうしろと? くるみサイズの脳みそしかないあやしいジャンガリアンベムスターがさすらう贖罪蹂躙(ゴシックペナルティ)

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  632  : 記事  35  : コメント  11677  : トラックバック  143

ニュース


片桐 継 は
こんなやつ

かたぎり つぐ ってよむの

大阪生まれ河内育ちなんだけど
関東に住みついちゃったの
和装着付師だったりするの
エセモノカキやってたりするの
VBが得意だったりするの
SQL文が大好きだったりするの
囲碁修行中だったりするの
ボトゲ好きだったりするの
F#かわいいよF#

正体は会った人だけ知ってるの

空気読まなくてごめんなさいなの


わんくまリンク

C#, VB.NET 掲示板
C# VB.NET掲示板

わんくま同盟
わんくま同盟Blog


WindowsでGo言語
WindowsでGo言語


ネット活動


SNSは疲れました

記事カテゴリ

書庫

日記カテゴリ

ギャラリ

イベント活動

プログラムの活動

鮎を食べるのは楽じゃない、その1~STAとMTAの話~

http://blogs.wankuma.com/esten/archive/2008/01/23/118945.aspx

の続き。前回はSTA鵜匠さんとMTA鵜匠さんに「この川全部の鮎」を注文しました。つまりこれは、「SELECT * FROM 川 where 魚 = 鮎」というSQL文をADOに処理してもらい、その結果を取得するようにした、と考える事ができます。ここで「あれ?これって本当にちゃんと鮎全部をとってこれんの??」と思った人、鋭い(笑)。そこで、ちょっと話は戻って、「SELECT * FROM テーブル というSQL文をADOに処理させる」という部分、つまり、「川全部の鮎を捕まえる為に鵜に何をさせるのか」についてここでは考えてみることにします。

SELECT * FROM テーブル Where 条件

誰もが一度は書くSQLではないでしょうか? あるテーブルから条件にあうレコードを全部取ってくるSQLです。このSQL文を処理するには、大きく分けて4つの方法があります。以下、DBをSQLServerとしてのサンプルコードです。

Adapterによる取得(同期処理)
(鵜匠一人に鵜が一羽。鵜が仕事に行くと鵜匠は戻ってくるまでずっと待つ)

  Public Sub UKAI_STA_Adapter()
    'リターン値の初期化
    Dim wGetDataTable As DataTable

    '内部ワーク
    Dim wParamValueArray() As String = {}

    'SQL文処理開始
    Using wSQLCommand As SqlCommand = New SqlConnection(StrConnectionString).CreateCommand

      wSQLCommand.Connection.Open()
      wSQLCommand.CommandText = "SELECT * FROM 川 WHERE 魚 = 鮎"

      Using wSQLAdapter As SqlDataAdapter = New SqlDataAdapter

        wGetDataTable = New DataTable
        wSQLAdapter.SelectCommand = wSQLCommand

        wSQLAdapter.Fill(wGetDataTable)

      End Using

      wSQLCommand.Connection.Close()

    End Using

  End Sub

Readerによる取得(同期処理)
(鵜匠一人に鵜が一羽。鵜が仕事に行くと鵜匠は戻ってくるまでずっと待つ)

  Public Sub UKAI_STA_Reader()
    Dim wGetDataTable As DataTable = New DataTable

    Using wSQLCommand As SqlCommand = New SqlConnection(StrConnectionString).CreateCommand

      wSQLCommand.Connection.Open()
      wSQLCommand.CommandText = "SELECT * FROM 川 WHERE 魚 = 鮎"

      Using wSQLReader As SqlDataReader = wSQLCommand.ExecuteReader()

        While (wSQLReader.Read())

          wGetDataTable.NewRow()
          wSQLReader.GetValues(wGetDataTable.Rows(wGetDataTable.Rows.Count - 1).ItemArray)

        End While
        wGetDataTable.AcceptChanges()
        wSQLReader.Close()

      End Using

      wSQLCommand.Connection.Close()

    End Using

  End Sub

BeginExecuteReader~EndExecuteReaderによる取得(非同期コールバック)
(鵜匠一人に鵜が一羽。鵜が仕事に行くと鵜匠はその間別の仕事をする)

  Public Sub UKAI_STA_CallBackReader()

    Dim wAsyncHandle As IAsyncResult
    Dim wChildCommand As SqlCommand
    Dim wCallBack As New AsyncCallback(AddressOf GetResult)

    wChildCommand = New SqlConnection(StrConnectionString).CreateCommand
    wChildCommand.CommandText = String.Format("SELECT * FROM 川 WHERE 魚 = 鮎")
    wChildCommand.Connection.Open()
    wAsyncHandle = wChildCommand.BeginExecuteReader(wCallBack, wChildCommand, CommandBehavior.CloseConnection)

  End Sub
  Protected Sub GetResult(ByVal pAsyncHandle As IAsyncResult)
    Dim wGetDataTable As DataTable = New DataTable
    Using wGetCommand As SqlCommand = CType(pAsyncHandle.AsyncState, SqlCommand)
      Using wGetResult As SqlDataReader = wGetCommand.EndExecuteReader(pAsyncHandle)
        While (wGetResult.Read)
          wGetDataTable.NewRow()
          wGetResult.GetValues(wGetDataTable.Rows(wGetDataTable.Rows.Count - 1).ItemArray)
        End While
        wGetDataTable.AcceptChanges()
        wGetResult.Close()
      End Using
    End Using
  End Sub

BeginExecuteReader~EndExecuteReaderによる取得(STA非同期)
(鵜匠一人に鵜が10羽。鵜が仕事に行くと鵜匠はその間別の仕事をし、鵜は仕事を終えたものから順番に船に戻ってくる)

  Public Sub UKAI_STA_CallBackReader_WithWait()
    Dim wAsyncHandle(10) As IAsyncResult
    Dim wHandles(10) As Threading.WaitHandle
    Dim wChildCommand(10) As SqlCommand

    For j As Integer = LBound(wChildCommand) To UBound(wChildCommand)
      wChildCommand(j) = New SqlConnection(StrConnectionString).CreateCommand
      wChildCommand(j).CommandText = String.Format("SELECT * FROM 川 WHERE 魚 = 鮎")
      wChildCommand(j).Connection.Open()
      wAsyncHandle(j) = wChildCommand(j).BeginExecuteReader(Nothing, wChildCommand(j), CommandBehavior.CloseConnection)
      wHandles(j) = wAsyncHandle(j).AsyncWaitHandle
    Next

    Dim wGetDataTable As DataTable = New DataTable
    Dim sPos As Integer = 0

    For j As Integer = LBound(wHandles) To UBound(wHandles)
      sPos = Threading.WaitHandle.WaitAny(wHandles)

      Using wGetCommand As SqlCommand = CType(wAsyncHandle(sPos).AsyncState, SqlCommand)
        Using wGetResult As SqlDataReader = wGetCommand.EndExecuteReader(wAsyncHandle(sPos))
          While (wGetResult.Read)
            wGetDataTable.NewRow()
            wGetResult.GetValues(wGetDataTable.Rows(wGetDataTable.Rows.Count - 1).ItemArray)
          End While
          wGetDataTable.AcceptChanges()
          wGetResult.Close()
        End Using

      End Using

    Next
  End Sub

BeginExecuteReader~EndExecuteReaderによる取得(MTA非同期)
(鵜匠分身10人に鵜が10羽。鵜が仕事に行くと鵜匠はその間別の仕事をし、鵜の仕事が終わったら分身が仕事をして本体へ帰還)

  Public Sub UKAI_MTA_CallBackReader_ManyWait()

    Dim wAsyncHandle(10) As IAsyncResult
    Dim wHandles(10) As Threading.WaitHandle
    Dim wChildCommand(10) As SqlCommand
    Dim wCallBack As New AsyncCallback(AddressOf GetResult)

    For j As Integer = LBound(wChildCommand) To UBound(wChildCommand)
      wChildCommand(j) = New SqlConnection(StrConnectionString).CreateCommand
      wChildCommand(j).CommandText = String.Format("SELECT * FROM 川 WHERE 魚 = 鮎")
      wChildCommand(j).Connection.Open()
      wAsyncHandle(j) = wChildCommand(j).BeginExecuteReader(wCallBack, wChildCommand(j), CommandBehavior.CloseConnection)
      wHandles(j) = wAsyncHandle(j).AsyncWaitHandle
    Next
    Threading.WaitHandle.WaitAll(wHandles) 
  End Sub
  Protected Sub GetResult(ByVal pAsyncHandle As IAsyncResult)
    Dim wGetDataTable As DataTable = New DataTable
    Using wGetCommand As SqlCommand = CType(pAsyncHandle.AsyncState, SqlCommand)
      Using wGetResult As SqlDataReader = wGetCommand.EndExecuteReader(pAsyncHandle)
        While (wGetResult.Read)
          wGetDataTable.NewRow()
          wGetResult.GetValues(wGetDataTable.Rows(wGetDataTable.Rows.Count - 1).ItemArray)
        End While
        wGetDataTable.AcceptChanges()
        wGetResult.Close()
      End Using
    End Using
  End Sub

と、ずらーっとサンプル列挙。とりあえず、全部、「川から鮎を取る」という仕事をさせるコードです。こんなにやり方がいろいろとあるわけで……。でもちょっとタンマ。これらのサンプルのうち、本当にほしい動作をしてくれるのは最初の3つだけです。残りの2つ、非同期の処理にはサーバー上でのテーブルロック問題とデータ取得の論理的な問題の二つがあります。

というわけで、続きはまた~

投稿日時 : 2008年1月24日 21:35

コメント

No comments posted yet.

Post Feedback

タイトル
名前
Url:
コメント