SQL Server でテーブルの内容を CSV 出力する事はそれなりに頻度があるかと思います。大体は BCP 等のユーティリティを利用して行うとか、それをスクリプトにまとめておくとか、そのような形ではないでしょうか。同じことをワークフローでも表現してみました。
今回は次のような流れのワークフローです。
- データベースからテーブル一覧を取得
- テーブルごとにデータを抽出
- 抽出したデータを CSV 出力
テーブル一覧を取得する部分は今回新規に用意したアクティビティですが、それ以外は今までの記事で利用したものとなっています。ロジックはこのような感じです。
1: Imports System.Activities
2:3: Public Class GetSQLTableListActivity4: Inherits AsyncCodeActivity
5:6: Private Const SQL_GETTABLE = "SELECT * FROM SYS.TABLES"7:8: Property ConnectionString As InArgument(Of String)9: Property Condition As String = ""10: Property TableList As OutArgument(Of String())11:12: Public Sub New()13: Me.DisplayName = "SQL Server のテーブル一覧を取得"14: End Sub15:16: Private Delegate Function GetSQLTableListDelegate(ByVal conString As String, ByVal conditionStrings As String) As String()17:18: Protected Overrides Function BeginExecute(ByVal context As System.Activities.AsyncCodeActivityContext, ByVal callback As System.AsyncCallback, ByVal state As Object) As System.IAsyncResult19: Dim conStr = context.GetValue(Me.ConnectionString)20: Dim asyncGetSQLTableListDel = New GetSQLTableListDelegate(AddressOf GetSQLTableList)21: context.UserState = asyncGetSQLTableListDel22:23: Return asyncGetSQLTableListDel.BeginInvoke(conStr, Me.Condition, callback, state)24: End Function25:26: Protected Overrides Sub EndExecute(ByVal context As System.Activities.AsyncCodeActivityContext, ByVal result As System.IAsyncResult)27: Dim asyncGetSQLTableListDel = TryCast(context.UserState, GetSQLTableListDelegate)28: Dim resultStrings = asyncGetSQLTableListDel.EndInvoke(result)
29: TableList.Set(context, resultStrings)
30: End Sub31:32: Private Function GetSQLTableList(ByVal conString As String, ByVal conditionStrings As String) As String()33: Dim result As String()34:35: Dim tabList As New DataSet36: Try
37: Using sqlConn As New SqlClient.SqlConnection(conString)38: sqlConn.Open()39: 'テーブル一覧の取得
40: Dim execSql As String = SQL_GETTABLE41: If conditionStrings.Trim <> "" Then42: execSql += " WHERE name like '%" + conditionStrings + "%'"43: End If44: execSql += " ORDER BY name "
45:46: Dim dataAdapter As New SqlClient.SqlDataAdapter47: dataAdapter.SelectCommand = New SqlClient.SqlCommand(execSql, sqlConn)
48: dataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey49: dataAdapter.Fill(tabList)50: sqlConn.Close()51: End Using52: Catch ex As Exception53:54: End Try55: '結果を String() に出力
56: If tabList.Tables.Count > 0 Then57: Dim resultList As New List(Of String)58: For Each childRow In tabList.Tables(0).Rows59: resultList.Add(childRow.item("name").ToString)
60: Next
61: result = resultList.ToArray62: Else
63: result = Nothing
64: End If65:66: Return result
67: End Function68:69: End Class
SQL Server では SELECT * FROM SYS.TABLES とすることでテーブル一覧が取得できますので、その結果を今回は String の配列として返却するようにしています。
そうして得たテーブル一覧に対して ForEach アクティビティでループ、その内部では取得したテーブル名を元にデータを取得、その結果を利用して ForEach アクティビティで更にループ、以前利用した CSVOutput なアクティビティを利用して1行ずつファイルへと出力しています。
このようにワークフローとして処理を記述すると、スクリプトやツールの知識がなくとも行われている処理内容が非常にイメージしやすくなります。このあたりが Workflow の醍醐味なのではないか、と個人的には思っています。
0 件のコメント:
コメントを投稿