SSIS Script Task: How do I set a variable in one package and use it in another - ssis

I need to use a variable I get in a Script Task in one package in a Script Task in another package. How can I make a variable with a scope that spans packages? Are there Project variables?

Prior to SQL Server Integration Services 2012, the only way to share a value between packages was to use Parent/Child configuration. You could actually share a value between them without using configurations but it was janky as all get out.
If you have no need of bi-directional communication, then you could have package A (one that computes the value in script task) start package B and use the /SET properties to assign a value to the variable
dtexec /file PackageB.dtsx /Set \Package.Variables[User::SharedVariable].Properties[Value];\"I was computed\"
In a SQL Server 2012 project deployment model, the Configuration concept has been replaced with Parameters. This is a bit more straight forward as you define Parameters and specify whether they are required. The Execute Package Task provides a nice mapping mechanism between local variables and expected Parameters.

In SSIS 2005 and 2008:
Declare a variable - say p as int - at the package level
Call your child package from the parent package.
Now, if you have a script task in the Child package, you can access the variable p like this:
1. Pass ReadOnly variable p in the Script Task Editor of Child package
2. To access the parent variable: Dts.Variables["p"].Value;
Notice, that I have not use "User::p" in any of the above two steps. I find this method straight-forward.
Make sure you do not declare a variable p at the child package level.
So, how does this method work? Think of the basic concept of the scope of a variable. The script task will keep "going up" to find the variable p. Going up means - it will first try to find it at task level, then container level, then package level, then finally at parent package level. (This is a simple explanation - technically each of these levels are containers.)
In SSIS 2012, you can also use parameters to pass the variable in ReadOnly mode. The method described above can also be used in SSIS 2012 with added advantage of being able to overwrite the value of the parent variable.

Related

How to re-establish the link between SSIS parameters configured at the project level and at the job level?

SSIS package parameters can be configured in 2 places.
Under Integration services catalog - on the project (right click, configure).
Under the SQL agent job step package configuration.
Parameters configured at project level automatically show up at the job level, and also the job level picks up any parameter changes made at the project level.
Where as if change is made to the parameter at the job level, then this doesn't update at the project level.
Suppose you change the value of the parameter at job level, then even if you reset the value to the original value (to match with the project level value), then any subsequent changes to this parameter at the project level doesn't update the value at the job level. Is there any way to re-establish the link between the project level and job level parameter?
I think I understand the question but let me know if I've missed the mark.
I have a project parameter, MagicNumber.
In the SSIS project in VS, it's -1.
I deploy to the SSISDB to a folder called Demo and Configure the deployed Project to have a value of 0. If I right click and run that package or create a job to run the package, it's going to use value of 0.
In a SQL Agent job, I then re-define MagicNumber to be 1 for all executions of that job. Even if I then go back into Configure the project to have 2 as my MagicNumber, all instances of this job will use 1 because we've specified that we are overriding the configured value.
If I created Job2 which runs the same package, it will use 0 and then 2 as MagicNumber because it's picking up the override from the Project Configuration.
Were you to deploy the same original .ispac file to a different folder, Pristine and ran that package, it's going to use -1 because that's the default configured value.
We put the first layer of configuration on all runs of the package from our project in the Demo folder by specifying MagicNumber is 0 and then 2. But the job allows us to add yet another layer of configuration by using a job specific level of configuration, 1.
If you decide 1 should be the default value, you update the Configuration for the project in the Demo folder. If you do nothing, then the SQL Agent job will still use the locally provided value so you then need to edit the job to remove the locally configured value and use the Project scoped configuration value.

SSIS 2008 User Variable in Expression for Execute Process Task

I have an SSIS 2008 package.
I have 3 user variables in the package. One is for an the environment, one is for the path for an executable, and the other is part of a message for an email.
I have a Script Task that sets the variable for the path (strAppPath) based on the environment variable.
strAppPath is used in an expression for the Executable property of an Execute Process Task. The job fails stating that the executable path for the Execute Process Task is not set.
I'm assuming that it is checking this path before the Script Task sets the variable.
Is there a way to work around this?
Right click on your Execute Process Task and select Properties. In the properties window, you will have a DelayValidation option that is currently set to False Flip that to True.
What is happening is that when the package starts, it goes through a validation phase to ensure everything is kosher before it begins (no need to start processing if something is broken). In your case, that full validation is not desired as the Execute Process Task won't be valid until right before it's time to run. The validation will occur, just that it is delayed until it is time for the task to begin. Make sense?

How can I dynamically set the location of an Execute Package Task in SSIS

I'm trying to set up a 'master' SSIS Package in SQL Server 2008 to run other 'child' packages. When developing the 'child' packages we have all the packages sitting on disk so we can easily debug them, so we use file connectors during development and can monitor the progress nicely.
When we deploy, we deploy the child packages to SSIS on SQL Server and then go through and change all the Execute Package Task's to use a location value of 'SQL Server' and set the PackageName. Once done, we deploy the 'master'.
What I'd like to do is use an Expression on the Execute Package Task to set the connection properties so we can configure this dependent on the environment. We have already setup a SQL Server configuration database using a view which checks the host name of the query and returns different values dependent on the query.
You have options. You're in the right frame of mind using expressions, but you might benefit from using configurations as well.
To use expressions, you would need to use a Script Task or Execute SQL Task to return back the list of files you want to work through.
You would either have to assign each returned value to it's own variable that is passed into the expression, or use a FOR EACH loop and work through a list, assigning the location of the child package each time.
The other option is to use configurations. My preference is to use a configuration table inside SSIS. If you have the same list of packages in each environment, you could either pass in the root directory and have an expression use that:
#[User::RootPackagePath] + "\PackageName.dtsx"
Or, you could simply have one record for each child package in the configuration table and that would be passed into the package.
Edit based on comments:
I was successfully able to configure a package to change via configurations to call a package from the file system then SQL.
I only needed to pass the Connection and PackageName for each. With SQL, it want a name from the connection manager (.\SQL2008R2 in my case) and the package name (\Package1). For the file system, PackageName is blanked out and the connection is a FileConnection in the connection manager.
You will have to keep both in the package, but you switch between the two.

How can I access a variable across script tasks within a package?

I have got two SSIS script tasks within a Sequence Container. I have declared variable StartTime in Script Task 1. I want to use this variable in Script Task 2.
Is it possible to access the variable StartTime within Script Task 2? How can I access the variable?
When you create variables in SSIS packages, you can define the scope of the variable. This scope defines which tasks on the Control Flow have visibility to the variables.
Sample package describing variable scopes:
Here is a sample SSIS package.
I have created a package with a sequence container and two Script Tasks within it. I have created four variables under different scope.
If you want to view all the variables defined under different scopes, you need to check the fourth button on the Variables pane. The option is indicated by the arrow in the screenshot.
Here is how the variables work in each of these scope:
StartTime_Package - This variable is declared under the scope MyPackage, which also happens to be the package name. This is the top level scope. This variable will be visible to all the tasks on the Control Flow.
StartTime_Sequence - This variable is declared under the scope Sequence Container, which is the given name of the sequence container task. This variable will be visible only to the Sequence container and the tasks within the sequence container.
StartTime_Task1 - This variable is declared under the scope Script Task 1, which is the given name of the first script task within the sequence container. This variable will be visible only to the first script task and no other tasks.
StartTime_Task2 - This variable is declared under the scope Script Task 2, which is the given name of the second script task within the sequence container. This variable will be visible only to the second script task and no other tasks.
How can I check if a task can access a variable or not?
Here is an easier way to identify if a particular task can access a variable or not. Let's uncheck the third option on the Variables pane.
Click on the Script Task 1. You will notice that the variable StartTime_Task2 is not displayed on the Variables pane because Script Task 1 does not have visibility to it.
Likewise, you can click on the task and verify which variables it can access.
You have to decide what the scope of the variable should be based on your requirements. If you are going to share the value of a variable across tasks, it is safe to declare it at the topmost package level scope.
If you are very sure that you will not access a certain variable outside of a particular task, it is safe to declare it at that task's scope level.
How to read a variable or write a value to variable using Script Task?
Double-click on the Script task, it will bring the Script Task Editor. You have to determine whether you just want to read the variable values or modify it within the task. I am going to modify a variable value and then display the value in a message box. To do that, I have to pick a variable that is already declared on the package and provide the script task the read and write access. Click the Ellipsis button against the ReadWriteVariables property
Select Variables will list the variables (both system and user level) to which the script task has access to. I am going to pick StartTime_Package variable.
You can see the variable now listed in the property. You can select multiple variables to. Click Edit Script so we can modify the C# code to write a value to the variable and then read it.
Paste the following code into the Script Task. First line assigns the value, here I am just adding 7 days to today's date. Second line displays the value of the variable in a message box.
public void Main()
{
Dts.Variables["StartTime_Package"].Value = DateTime.Now.AddDays(7);
MessageBox.Show(Dts.Variables["StartTime_Package"].Value.ToString());
Dts.TaskResult = (int)ScriptResults.Success;
}
If we run the package, it will display the value in message box. The package was executed on November 1, 2012 and you can that the package is displaying the modified value of November 8, 2012.
Hope that gives you an idea about variables scope within SSIS.
Make sure the scope of the variable (StartTime) is Package - that should do. Variable is available for use across the package.
In the first script task, add your variable as a Readwrite variable and maybe assign some value in the script.
In the second script task also, add it as a read or readwrite variable and you can reference it there.

Problem inserting a user variable in connection expression

I am trying to import 110 excel files into a sql server database in SSIS2008.
I am at the the point where I have dragged in my foreach loop container, pointed to the correct folder. I have made a string variable (with foreach loop scope) and set the default value to a file in the source folder of excel files.
When I try to build a connection string expression and try to find the user variable it is not in the list. The only variables in the list are system variables.
Does anyone have any idea where I might be going wrong. I feel that I have set the correct scope by defining the string variable from the foreach loop.
(The User::FilePath variable that I made is not visible in the package explorer either.)
Thanks.
I find I generally have a better SSIS experience when I keep my variables at the package level. I suspect the connection manager doesn't like the connection string variable only being visible in the loop and that may be causing it some heartache for design-time validation. The user variable(s) you've created are visible, just not visible at the scope you're looking at. If you've clicked on the canvas/background of SSIS, you'll only see package level variables. My suspicion is the variables are in the foreach loop or possibly even on the dataflow or other tasks within the foreach container.
If you really want to find where you created those variables, look at the unused tab "Package Explorer". Keep expanding Executables and looking at the Variables item until you find your missing variables.
Finally, if you have variables at the "wrong" level, user BIDS Helper. Even if you have the variables at the right level, grab BIDS Helper. It's free and it really improves the package development experience.