3

I am using SQL Server 2012 and I need to create an SSIS package that will run a list of T-SQL queries from a specific folder.

My list of T-SQL queries have been named starting with '01 (name of query).sql' and the folder contains a list of 25 queries. I need the task to run these queries starting with query '01...' to '25...'

Can this be created in an SSIS package? If yes, which task should I use?

Update 1

I tried the first method suggested by @Hadi and the script task throws the following exception

Error: Exception has been thrown by the target of an invocation

screenshot of my task in SSDT

enter image description here

Script Task VB code

 <Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute()> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
 Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase

 Public Sub Main()

    Using sr As New IO.StreamReader(Dts.Variables("strFilename").Value.ToString)

        Dts.Variables("strQuery").Value = sr.ReadToEnd()
        sr.Close()

    End Using

    Dts.TaskResult = ScriptResults.Success
End Sub

End Class

Variables

enter image description here

Hadi
  • 36,233
  • 13
  • 65
  • 124
user3115933
  • 4,303
  • 15
  • 54
  • 94
  • Foreach Loop over the files in the folder (Collection > Foreach File Enumerator, choose folder, use *.sql for Files). Create a variable. Assign the file to the variable. Put Execute SQL Task in the loop container. Use the variable as the source of the Execute SQL Task. – Jacob H Jan 18 '18 at 17:56
  • Thanks. I am a bit lost at the "Create a Variable" step! How do I do this? – user3115933 Jan 18 '18 at 18:27
  • Should be an option in the dropdown for New Variable under the Variable Mappings. Or add one from the SSIS>Variables menu first. – Jacob H Jan 18 '18 at 18:29
  • Sorry to be a pain here. I am new to this. I have already created the Variable. How do I "Assign the file to the variable"? – user3115933 Jan 18 '18 at 18:59
  • Ok, I have managed to progress with the Variable issue. Now, when running the package in SSDT, I am getting the following error message: [Execute SQL Task] Error: An error occurred with the following error message: "Access to the path 'C:\RUN\CleaningQueries' is denied.". Any ideas on how to turn this around? – user3115933 Jan 18 '18 at 19:36
  • @user3115933 have you tried my suggestion? The links contains much details on that – Hadi Jan 18 '18 at 19:49
  • @Hadi Not yet as I had already progressed with the comments provided by Jacob H. I will give yours a try tomorrow morning (already very late here!). – user3115933 Jan 18 '18 at 20:10

2 Answers2

6

(1) Using Script Task + Execute SQL Task

  1. Add a Foreach Loop container
  2. Choose the type = File enumerator
  3. Select the Folder containing the .sql files as Source Directory
  4. Select the Fully qualified file name option
  5. Go To variable mapping Tab, Map the result to a Variable (Create new one ex: @[User::strFilename])
  6. Create a Variable of Type String @[User::strQuery]
  7. In the foreach Loop container add a Script Task and Select @[User::strFilename] as ReadOnly Variable and @[User::strQuery] as ReadWrite Variable
  8. Inside the Script Task Write the following Code (Choose Visual Basic as Language):

    Try
    
        Using sr as new IO.StreamReader(Dts.Variables("strFilename").Value.ToString)
    
            Dts.Variables("strQuery").Value = sr.ReadToEnd()
            sr.Close()
    
        End Using
    
        Dts.TaskResult = ScriptResults.Success
    
    Catch ex as exception
    
        Messagebox.Show(ex.Message)
        Dts.TaskResult = ScriptResults.Failure
    
    End Try
    
  9. Add an Execute SQL Task linked to the Script Task, and Select the ConnectionString property, then choose SQLSource Type property = Variable

  10. Select @[User::strQuery] as SourceVariable

(2) Using Execute Process Task

Use a foreach loop container to loop over these files, then use an Execute process task to run these queries using SQLCMD.

Additional Information:


(3) Using a batch file

Also you can achieve this without SSIS, just using a batch file .BAT that you create with notepad:

Hadi
  • 36,233
  • 13
  • 65
  • 124
  • 1
    Thanks. I will go through those documentation. I will need to add this package as a step in sql agent job process that will run on a daily basis. – user3115933 Jan 18 '18 at 18:58
  • I think these links will helps you to do that, if you need more details just give me a feedback – Hadi Jan 18 '18 at 19:00
  • The link "Run Transact-SQL Script Files Using sqlcmd" gives an example where there is a single query. How do I deal with multiple queries in the folder? – user3115933 Jan 18 '18 at 20:12
  • @user3115933 - you will run one file every loop. – KeithL Jan 18 '18 at 20:14
  • @user3115933 i added a new method, you can check it – Hadi Jan 18 '18 at 21:23
  • @Hadi Thanks a lot for your efforts! I have just tried your solution (1). I followed each step closely and when I run it in SSDT, I get the following error: "Error: Exception has been thrown by the target of an invocation." – user3115933 Jan 19 '18 at 09:34
  • @Hadi I have added a screenshot to show the flow. Is it correct? – user3115933 Jan 19 '18 at 09:41
  • Yes, check that the variablename is correct. The name is case sensitive – Hadi Jan 19 '18 at 12:04
  • If it still not working, just provide the Script task full code so it will be more clear – Hadi Jan 19 '18 at 12:06
  • If it still not working, just provide the Script task full code so it will be more clear – Hadi Jan 19 '18 at 12:06
  • @Hadi Script Task VB code + Variables Window screenshot added above. – user3115933 Jan 19 '18 at 12:51
  • 1
    @user3115933 i think that the problem is with strFilename variable, there is an error reading the path, or the variable doesn't contains a correct value, check that you have assigned the value correctly to `strFilename`. Also you can try a `TRY Catch` block to read the exception. check my code update for more info – Hadi Jan 19 '18 at 19:13
  • @user3115933 read more about foreach loop container, and how to assign values to variable here: https://www.red-gate.com/simple-talk/sql/ssis/ssis-basics-introducing-the-foreach-loop-container/ – Hadi Jan 19 '18 at 19:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163531/discussion-between-user3115933-and-hadi). – user3115933 Jan 20 '18 at 07:02
1

I upvoted Hadi, as I learned something new.

But this is how I do it with a script task. Dealers choice.

//Read SQL to string
System.IO.StreamReader sr = new System.IO.StreamReader(Dts.Variables["ForEachFilePathName"].Value);
string sql = sr.ReadToEnd();
sr.Close();

string cstr = Dts.Variables["connString"].Value;
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(cstr))
{
   System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(sql, conn);

     conn.Open();
     cmd.ExecuteNonQuery();
}
KeithL
  • 5,348
  • 3
  • 19
  • 25
  • I forgot the reason I did this and now reading other responses, it is because I really use this as a script component source where I write the results out to the data flow. I converted it to meet your needs. – KeithL Jan 18 '18 at 20:32