SSIS: Conditional Split result to variable - sql-server

I have condition where I need to feed conditional split result based on condition (will be just one int value) to variable. Can some one help how to do this?
My actual package (Data flow):
XML Source --> Conditional split (based on condition) 2 outputs..one result based on condition (will be just one int value) need to pass it on to variable. How to achieve this?

Pure SSIS way - consume your dataflow into a Recordset Destination and then iterate through it with ForEach Loop, assigning value to the desired variable.

you have to use a script component to achieve this:
Create a script component (Choose it's type as Destination)
Double click on script component and Choose your Variable as a ReadWrite Variable. (in my example the variable is named Result
Inside the script window write the following code
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
If Not Row.inColumn_IsNull Then
Variables.Result = Row.inColumn
End If
End Sub
Side Note: Variable value does not change before dataflowtask execution is finish, to use the new value you have to continue your work in another dataflowtask

I know two ways to realize this.
First: Do it with a C# script component, this is the easiest way.
Just put a script component behind your conditional split, select your variable as "ReadWrite", then set it like that in the code:
Dts.Variables["yourvariable"].Value = Input0Buffer.Yourcolumn
I don't have access to SSIS right now, so I can't give you the exact code, but this should get you started.
Second: Write to a table and read it back with Execute SQL task. I don't really like this way ;-)

Related

ssis reset variable before reusing

I have a variable #[User::fileExist] within my ssis package which I use to return a result if a file exists.
It is defaulted to 0 then if a file exists it will return 1. I decided to re use this variable later on in the package how do I reset this variable before using it again
Using Expression Task
SQL Server 2012 or newer
You can use an expression task to achieve this. just add an expression task to your package and use the following expression
#[User::fileExist] = 0
Read more #:
Expression Task
Use an Expression in a Data Flow Component
Using Script Task
Or you can use a script task to achieve this, just add a script task to your package, choose this variable as a ReadWrite Variable and inside the script write the following code (you have to select Microsoft Visual Basic as script Language):
Public Sub Main()
Dts.Variables.Item("fileExist").Value = 0
Dts.TaskResult = ScriptResults.Success
End Sub
You can reset the value of the variable with a Script task.
How about skipping the reset and just setting it:
Dts.Variables["fileExists"].Value = System.IO.File.Exists(filePath);
One of the standard and more transparent approaches would be creating sequence container where you want your variables to be alive. Giving them the scope of that container you will ensure that on the next iteration they are re-created.

How to pass a two dimensional list/array between groovy scripts in soap ui?

Problem statement: We need a way to pass a two dimensional list (or array) from one groovy script to other scripts ( to assert values from multiple DB2 tables in other scripts].
Some Background:
Step1: Based on our input xml payload we are capturing the list of nodes (and child elements) in a two dimensional list [][]. [Done]
Step2: Now we want to use the values from each of this list to assert with respect to values in DB2 tables [Also done, however keeping both step1 and step2 in same groovy script].
What we want is to to be able to pass the 2dimensional list from step1 in step2. Specially important since we have multiple tables and we dont want to either add all table steps in one big groovy script Or to duplicate step1 code in each Db2 validataion script.
We read about setting each element value from list at test case level and then reconstructing the array back but we are hesitating to use that method due to (varying &) huge size of list elements (in thousands). Question is: Are there any clean ways to achieve this?
Thanks!
As you are aware of the limitation of the earlier solution, which would only work (sharing of object between the groovy scripts) if the test case is run and does not work if individual steps are run.
Here I want to provide an approach which over comes that by using groovy's meta programming.
In script 1, have the below code:
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase
WsdlTestCase.metaClass.myList = [1,2,3,4,5]
In script 2, have the below code:
log.info "From script 2: ${context.testCase.myList}"
assert [1,2,3,4,5] == context.testCase.myList
The above even works if individual steps are run.
Hope this is helpful.
EDIT: come to understand that user required to update the list repeatedly and with metaClass user couldn't update the list. Here is the alternative:
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase
WsdlTestCase.metaClass.myObject = new Expando(myList: [1,2,3,4,5])
log.info "list initialized: ${context.testCase.myObject.myList}"
WsdlTestCase.metaClass.myObject = new Expando(myList: [1,2,3,4,5,6,7])
log.info "list updated: ${context.testCase.myObject.myList}"
You can use context
That's real working Groovy Script steps.
step1:
def array = ['Kyiv', 'Boryspil', 'Kharkiv', "L'Viv", "Odesa"]
context.setProperty('cities', array)
log.info( 'script1: '+array )
step2:
def array = context.getProperty('cities')
log.info( 'script2: '+array )
assert array.size()>0
Note:
If you run just one step, then there will be absolutely
independent context.
But if you run the whole testcase then there will be context shared
for the whole testcase.
You can use Run from here context menu in your test case window to run from exact step.

VBA excel passing an array to sub fired by button

As in title I would like to pass an array to the sub which is executed by a button (That's why I don't know ho to pass it to the sub). Array is calculated in the Sheet before you can exectue sub with the button.
I've tried using:
Option Explicit On
Public My_array(1 to 10)
But I have received an error that I can not do that command with array, const etc.
What is the correct way to do it?
I think there is some terminology we can try to clear up: you're not actually passing the variable to the button's procedure. A publicly scoped variable is going to be available within that procedure and does not need to be "passed".
Note: I'm not sure what you mean by "Array is calculated in the Sheet". Unless you are using some event procedure to calculate an array in memory (probably you are not, because you don't have the array scoped or declared properly to do this...), this statement can't possibly be true.
Your declaration should be like:
Public myArray(1 To 10) As Variant 'or As String, As Double, etc.
You can omit the As ... part and it will be type Variant. if you need more strongly-typed array, then you will need to specify.
Also, On is not a legal keyword after the Option Explict statement. So, remove that. But keep Option Explicit in all of your modules.
The error message you receive hints at the solution: You can't put public declarations in object modules. An object module is a Worksheet, Workbook, UserForm, or Class module in the VBE.
You can only put these declarations in a normal code module.
Solution: Move the declaration of myArray to a normal code module.

VBA EXCEL - Public Array losing its value at each new code execution

I am currently developing a code in VBA Excel.
This code generates a 3 dimensional array based on userinputs in the worksheets.
The idea is to re-run this code every time userinput is changed.
But due to heavy calculation time, I want to keep previously calculated data in the array and only amend the array for the rows / columns that have received new user input.
My original idea was therefore to:
declare the array as public and
use "redim preserve" for each new code execution (i.e. each new update)
However, I realise that at every new code execution, the array comes in empty and the full calculation is re-run...
Could someone help to solve this issue?
Thanks in advance
Al
Public Function UseTestVar()
Static TestVar(10) As Integer
Debug.Print TestVar(1)
TestVar(1) = TestVar(1) + 1
End Function
Sub Test3()
UseTestVar
End Sub
Every execution time the TestVar(1) value is incremented.
Edit;
So yes, you need to have a function to "hold" you the "global" variable, and use that function to do all the stuff with it... or return it, or... Without knowing your code I must leave it to you to figure out the working implementation.

Foreach Loop Microsoft SSIS - equivalent to break statement

Within a Foreach loop in SSIS is there a way that if a task fails you can break out of the loop to the next iteration?
I am looping over xml files and performing a lookup using values within this file, if the lookup doesn't return any values i'd like to report on this and then not perform any other tasks for this file. If there is no equivalent to a break statement how else can this be achieved?
You could also use a 'for' loop with a boolean condition such as looping while a variable is equal to true. Then when you want to break out of that loop, simply change the value of that variable to false and then you will break out of the loop.
Answering your question...a foreach loop, loops over a collection and other enumerable constructs so long as they exist to loop over. So you could either find a workaround, or just use a 'for' loop instead of a 'foreach' loop. That way you have more of a programming type control over the loop because you set the condition expression.
And yet another way would be to put a sequence container into your loop then put the conditional steps in the sequence container. Any decision that should 'continue' need only exit the sequence container.
Very simple to implement with all the control you could want including error trapping.
The lookup can redirect if there are no values returned, away from the successful flow.
You need the rest of your foreach loop to know there has been an error, so one way would be to set a package variable on error, just before you do the logging.
Then, in the 'success' arrow after your lookup you can change it to a conditional success, so that it only proceeds if the value of the variable is not the error value.
So I just had that problem and solved it by a) directing the failed task to a dummy task which did nothing and ended and b) setting the 'FORCEEXECUTIONRESULTS' to 'SUCCESS', which plowed through just the way I wanted it to.

Resources