What I would now like to do is have a "for each" loop container that processes information (including queries) that are stored in a SQL Server table. Here is the structure of that table:
create table dbo.Monthly_Report_Queries
(
seq_num real not null
, worksheet_name varchar(32) not null
, create_statement varchar(400) not null
, data_query varchar(7500) not null
)
The seq_num column is used to control the order of the queries (for my "for each" loop container); the worksheet_name column has a valid Excel worksheet name (31 or fewer characters) on which the data will be placed; the create_statement column has a valid Excel statement to create a worksheet with the desired column names and data types; the data_query column has a SQL Server T-SQL query to get from the database the information to place on the corresponding worksheet.
I have been successful at getting the worksheets created, and at getting a Script Task to the point where it executes the data_query and returns the results to the Script Task. I am now stuck at deciding how best to use the Script Task to get the data onto the worksheet (or even how to get the Script Task to put the data there even in a poor way).
Here is my VB code so far:
' Microsoft SQL Server Integration Services Script Task
' Write scripts using Microsoft Visual Basic
' The ScriptMain class is the entry point of the Script Task.
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.OleDb
Imports System.IO
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Public Class ScriptMain
' The execution engine calls this method when the task executes.
' To access the object model, use the Dts object. Connections, variables, events,
' and logging features are available as static members of the Dts class.
' Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
'
' To open Code and Text Editor Help, press F1.
' To open Object Browser, press Ctrl+Alt+J.
Public Sub Main()
'
' http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.dts.tasks.scripttask.scriptobjectmodel.connections(SQL.90).aspx
'
Dim myADONETConnection As SqlClient.SqlConnection
Dim command As New SqlCommand()
myADONETConnection = _
DirectCast(Dts.Connections("ORION.TRS1").AcquireConnection(Dts.Transaction), _
SqlClient.SqlConnection)
MsgBox(myADONETConnection.ConnectionString, _
MsgBoxStyle.Information, "ADO.NET Connection")
command.CommandTimeout = 30
command.CommandType = CommandType.Text
command.CommandText = CType(Dts.Variables("DataQuery").Value, String) ' Get query from DataQuery variable
command.Connection = myADONETConnection
' Open the connection and execute the reader.
' myADONETConnection.Open() ' already open
' MsgBox(command.CommandText, MsgBoxStyle.Information, "About to execute...") ' examine the query
Dim reader As SqlDataReader = command.ExecuteReader()
If reader.HasRows Then
Do While reader.Read()
MsgBox(reader(0), MsgBoxStyle.Information, "Query output...")
Loop
Else
MsgBox("No rows returned.", MsgBoxStyle.Information, "Query output...")
End If
' myADONETConnection.Close() ' do not close; leave open
Dts.TaskResult = Dts.Results.Success
End Sub
End Class
I would appreciate any links to websites that will help me decide which connection manager to use for writing data from a Script Task. (I am creating the worksheets in the For Each loop using an Execute SQL Task and an Excel Connection Manager. Should I use an ADO.NET connection to the same Excel file to write the data from the Script Task?) Are there better ways to get the query output than ExecuteReader()? Would it help to put the ExecuteReader() output into an array, and maybe use some form of VB command to place the entire array on the worksheet (rather than "cell by cell")? (I never expect to have more than a few hundred rows returned by any one of the queries.)
Thanks for your help with this -- and for the many wonderful postings I have found on the Web that have helped me so far.
Dan