SSIS forcing task successful but parent fails - ssis

I have a sequence container with two tasks. First task is ok to fail but if the second task fails the container should fail. I set the properties for the first task as
ForcedExecutionValue=0
ForceExecutionResult=Success
ForceExecutionValue=True
If both tasks are successful - regardless of the method why is the container (and therefore the package) failing ?
Tried to set a breakpoint on the first task for onerror, taskfailure and warning but none are firing which seems strange.

Think I was able to work this out. For the first task in addition to the settings in OP, the task needed OnError handler with propagate=false so the error would not be passed to the container. Also make sure DisableEventHandlers = false

Related

SSIS checkpoints are not re-starting correctly, skipping NON-checkpointed tasks

I have an SSIS package where the checkpoints are not behaving as I understand that they should.
To simplify, this is the kind of setup:
Imagine a package with two containers in a serial flow (Container 1 executes then Container 2). Checkpoints are configured and ONLY Container 2 is setup as "Fail Package on Failure". It is desired that Container 1 is ALWAYS completely re-run even in a job restart unless the job made it to Container 2, then it should restart at a checkpoint in Container 2.
Container 1 has a major table copy step that obviously can't be restarted using checkpoints since checkpoints do not track db updates. So Container 1 has logic that allows it to restart the "old fashion way" by interrogating the source and destination, determining where it left off when it failed, and updating package variables accordingly that are used to drive the main query so it will resume at the row it left off. This works flawlessly if I delete the checkpoint file after the failure and restart.
I intentionally cause a failure during the table copy in the non-checkpointed Container 1. But with the checkpoint file left at failure, it doesn't work! For some reason upon restart, it acts as if Container 1 is also checkpointed. It does NOT run the steps in Container 1 that will interrogate the source and destination, nor the steps that update the variables and instead immediately goes to the step of the table copy in Container 1, using variable values from the failed run, which causes the copy to start at an incorrect position (and end up with pk violations in insert). Every task in Container 1 has "Fail Package on Failure" set to FALSE. They also have "Fail Parent on Failure" set to false in case that matters. Why does it act as if Container 1 is checkpointed? Why doesn't it run all steps in Container 1 from the beginning since the package has not even gotten to the first container that is checkpointed (Container 2)? What behavior am I missing with these checkpoints?

How to set up SSIS parent package such that 4 child packages can run at the same time with different parameter values passed in?

I have created a child SSIS package that executes according to the "ProcessName" variable value that is specified initially. Now, I wish to create a parent package such that I can execute 4 child package tasks with different ProcessName values passed in to be executed in parallel. How can I maintain my child package and pass in different values to each of the 4 execute packages task such that the ProcessNames variable values are different for each of them? I am new to SSIS and would deeply appreciate if someone could advice or give a direction on how I could go about doing so.
I would see this as a pattern like the following
The "trick" here is that within each Sequence Container, SEQC, I need to define my variable that holds my parameter value. That variable needs to be scoped to the container - otherwise, there is only one SSIS variable and the 4 processes that attempt to initialize that value will be in conflict.
In the SSIS Variables menu, there is a Move Variable icon (second one listed)
Here you can see that I have ParameterValue defined in both "SEQC Opt 1a" and "SEQC Opt 1b" and they're initialized with different values.
The first step within the Sequence container is an Execute SQL Task where I pull back the intended parameter value. Maybe that is not needed in your case but it can be helpful to have a repository of run-time values. In the case of 1b, this is much more what my execution pattern looks like. I have a query that pulls back any packages to be run within the scope of this container and the starting value. e.g.
ContainerName|PackageName|StartingValue
SEQC Opt 1a |Child0.dtsx|100
SEQC Opt 1a |Child1.dtsx|200
SEQC Opt 1a |Child2.dtsx|300
SEQC Opt 1b |Child5.dtsx|600
SEQC Opt 1b |Child6.dtsx|700
SEQC Opt 1b |Child7.dtsx|800
This table pattern allows me to dynamically run packages in both parallel and in serial. Assuming Child7 and Child2 in the above set are very slow but the other 4 packages are relatively fast. The fast ones would start up, do their work and complete and the next runs. There are limits to how many parallel operations can fire at once so you can't scale infinitely across processes so a balance of serial and parallel operations makes sense.
Once you have your pattern working for one sequence container: copy, paste, rename and assuming you lookup in a table based on the task name as I show above, it's ready to go.
NOTE for everyone reading this answer: This answer is not full/complete with examples/full steps. From comment above I am posting this now so requestor can see it and get started.
This was from notes I wrote myself a long while back on how to do this for myself. I am posting it as answer as it is helpful and too large to post as comment. Plus I have not rewritten anything in what wrote for myself and what I am posting.
Currently I can not find my full code yet to post full details/steps. If/when I do I will post here, but this should be good details on what/how to do it. Plus this gives info on how to handle child package error trapping as well.
-- my notes I saved for myself posting as answer:
Steps for creating child packages:
Create any variables needed in the child package
Create the coorisponding variable name in the parent package (the name doesnot have to be the same, and maybe want to name it something to identify it as a child package variable)
Child Package:
Need to set up: Package Configurations
a. Right click on package and click Package Paramaters
b. Click the checkox to Enable Package configurations
Click Add and set the paramaters:
a. Configuration Type: Pareknt Package variable
b. Specify the configuration setting directly: Put the parent variable name in here that the child package is going to access
c. Click "Next"
d. In "Objects" window scroll down to the variable you are setting from the parent variable name you selected above and click the "Value" option under Properties for that variable name
e. Click "Next"
f. Under Configuration Name: Set a detailed name for what this variable is/does.
Error Handling (NOTE: This is not required but you wont capture the child error messages if you dont do this):
a. Go to Event Handlers Tab
b. Under drop down (on top right) select OnError
c. Add a Scrit Task
d. Pass as read only variables:
System::ErrorDescription
System::SourceName
System::PackageName
e. Copy/paste the code below into the script task uin the Main() function.
----- this is for the error handling
public void Main()
{
// build our the error message
string ErrorMessageToPassToParent = "Package Name: " + Dts.Variables["System::PackageName"].Value.ToString() + Environment.NewLine + Environment.NewLine +
"Step Failed On: " + Dts.Variables["System::SourceName"].Value.ToString() + Environment.NewLine + Environment.NewLine +
"Error Description: " + Dts.Variables["System::ErrorDescription"].Value.ToString();
// have to do this FIRST so you can access variable without passing it into the script task from SSIS tool box
// Populate collection of variables. This will include parent package variables.
Variables vars = null;
Dts.VariableDispenser.GetVariables(ref vars);
// checks if this variable exists in parent first, and if so then will set it to the value of the child variable
// (do this so if parent package does not have the variable it will not error out when trying to set a non-existant varaible)
if (Dts.VariableDispenser.Contains("OnError_ErrorDescription_FromChild") == true)
{
// Lock the to and from variables.
// parent variable
Dts.VariableDispenser.LockForWrite("User::OnError_ErrorDescription_FromChild");
// Need to call GetVariables again after locking them. Not sure why - perhaps to get a clean post-lock set of values.
Dts.VariableDispenser.GetVariables(ref vars);
// Set parentvar = childvar
vars["User::OnError_ErrorDescription_FromChild"].Value = ErrorMessageToPassToParent;
vars.Unlock();
}
Dts.TaskResult = (int)ScriptResults.Success;
}
Parent Package:
Add this variable to propertly capture the child error messages (not required but you wont capture chidl error messages if you dont):
variable: OnError_ErrorDescription_FromChild
Error Handling(NOTE: This is not required but you wont capture the child error messages if you dont do this):
a. Go to Event Handlers Tab
b. Under drop down (on top right) select OnError
c. Add a Scrit Task
d. Pass as read only variables:
User::OnError_ErrorDescription_FromChild
e. Copy/paste the code below into the script task uin the Main() function.
----- this is for the error handling
public void Main()
{
// get the varaible from the parent package for the error
string ErrorFromChildPackage = Dts.Variables["User::OnError_ErrorDescription_FromChild"].Value.ToString();
// do a check if the value is empty or not (so we knwo if the error came from the child package or the occurent in the parent package itself
if (ErrorFromChildPackage.Length > 0)
{
// Then raise the error that was created in the child package
Dts.Events.FireError(0, "Capture Error From Child Package Failure",
ErrorFromChildPackage
, String.Empty, 0);
//Dts.TaskResult = (int)ScriptResults.Failure;
} // end if the error length of variable is > 0
Dts.TaskResult = (int)ScriptResults.Success;
}
NOTES:
For error handling:
a. The child package error handling is written so it wont fail if the variables or error handling does not exist in parent package.
b. If you include the error handling (and variable) in the parent package it MUST exist in the child package though.

Foreach Loop SISS not moving to next ieration in case it fails

I am working with SSIS and inside a Foreach Loop I have got an "Analysis Services Execute DDL task". It has two iterations. If it fails on the first, the loop is not moving on to the second iteration. Is there any way I can make it move to next iteration?
Here is how you could continue a loop after an error
Likely what's happening is that the task's failure causes the loop container's MaximumErrorCount threshold to be met. This causes the loop's ExecutionResult to be set to failure, stopping further loop iterations. (More on how MaximumErrorCount works [on my blog].)
If you don't want the task's error to stop further loop iterations, options include:
Raise the loop's MaximumErrorCount to a higher value or set it to infinity.
Set the loop's ForceExecutionResult to success to override MaximumErrorCount's setting ExecutionResult to failure--keeps the loop iterating regardless of what ExecutionResult gets set to.
For added flexibility, I think you can use an expression to control ForceExecutionResult.
Add an OnError event handler on the task that stops event propagation--keeps the error from bubbling up from task to loop container.
Get rid of the loop and create multiple Analysis Services Execute DDL Tasks--bypasses the problem altogether.
Without understanding the big picture of what you're trying to do, it's hard to make a recommendation as to which approach is best.

Recurring errors in Loop ( SSIS )

I have an SSIS package where I am processing some files in a ForEach loop.
In the loop I have a data flow task which does the processing. I have made sure that the loop doesn't stop even if there is bad file by setting the maxerror count of the loop to 0. I tried to catch the error in a message box using the script task on ON ERROR Event handler of the loop container. Instead of getting one error , I get three.
Popagate is set to false on the data flow’s OnPostExecute event.
Please help.
Main package - Loop Task - Data Flow Task
The reason you are getting 1 or more errors in the script task for on Error event handler is because in case of any error inside the child controls for the container , the event is raised from the Data Flow task to the ForEach which is furthr carried upto the package level.More over setting propogate variable to false won't work in this case because MaximumErrorCount which you set to 0 overrides any propogate settings in its child components.
Generally i try to create one ErrorCount variable of type int and in the script task for the event handler of the DFT i check the count
if (int.Parse(Dts.Variables["User::ErrorCount"].Value.ToString ()) == 0)
{
Dts.Variables["User::ErrorCnt"].Value = 1;
//Do your logging operation or any operation
}
So in this way the first time event handler is fired ,it sets the variable ErrorCount to 1 so subsequent errors in DFT will fail the IF condition inside script task.
If you just have one component inside the ForEach loop ,i suggest you to use either of the below method
MaxErrorCount property for the ForEach Loop
Create a event handler for the DFT .Set the propogate variable to False and write the above code to check for number of errors.
I generally tend to use the 2nd method instead of Setting MaxErrorCountbecause that give me more flexibility to handle individual component level errors
For more details check this MSDN link which explains how event handlers in SSIS works

SSIS -- Allow a task to fail but have the package succeed?

Is there a way to allow a script task to fail, yet have the package execution result based only on the other tasks' execution results? For example, I have 5 tasks. I don't care what task 2's result is, but if any of the others fail, I want the package to fail. Otherwise, I want it to succeed...
This possible?
As well as setting FailPackageOnFailure on the task you should also set MaximumErrorCount on the package itself to something greater than 1. The task will still increment the packages error count and if the error count exceeds MaximumErrorCount then the package can/will still fail.
Try setting FailPackageOnFailure to False in the Task's Properties.
Next option will not actually fail your tasks, but may work for you:
Try wrapping your code into try catch and use finally to set Success for 2 tasks that you don't care about.
try
{
// Do work here
}
catch
{
// log errors here
}
finally
{
Dts.TaskResult = (int)ScriptResults.Success;
}