How to programmatically change the work flow between SSIS control flow tasks? - sql-server

I have an SSIS package, which depending on a boolean variable, should either go to a Script Task or an Email task.(Note: the paths are coming from a Script Task)
I recall in the old dts designer there was a way to do this via code. What is the proper way to accomplish this in SSIS?

Isn't a Conditional Split a data flow
task, which takes a row of data and
pushes it in one of two directions
according to some property of the
data???
Oops, that is correct. I found this blog entry which explains how to do proper control flow conditional branching based on boolean values.

In control flow, drag the green arrow to the email task, then right-click on it and you will see you can set it from 'Completed' to 'Conditional', then you can set an expression on the condition. The arrow will then turn blue. You should then be able to drag another arrow to the other script, and set that to conditional.
I have this set-up often, many times you want to email if a certain condition applies. The standard syntax for the conditional constraints is something like:
#[User::SendEmail] == True
Assuming your SendEmail variable is a boolean. If you use anything else, just construct an expression that evaluates to either true or false.
Remember to set the conditionals to OR instead of AND, otherwise it won't complete unless it can take both routes!

A Conditional Split task does what you want. Add the Conditional Split task, add in an additional output (a default output is provided), and set up the Condition for that output. Then just tie the outputs (default and new) to the Script and Email tasks as appropriate.

Related

Is it possible to view queries with resolved variables in ODI's code executions?

In ODI's operator tab you can check the state of an execution, and inside each execution the SQL used for each transformation. On the project i'm working on we use a lot of variables when developing our ODI projects. The problem is that to debug the SQL code we have to replace the variable names with the values by hand.
Is it possible to view the executed code with the variables resolved? What would be a good workaround for this? Thanks.
First thing you need to do is to execute the mapping with log level 6 (by default it is in 5).
Then you need to click in the icon on the top-right when you check the executed code in the operator:
I hope this works for you.

More on ui-grid row filtering

Long version of the question
I have a complex filtering operation that I'm trying to implement for a ui-grid application. Essentially, I have a big grid with lots of columns, each having the typical filter fields at the top of the columns. That works great.
Then I have an extra analysis step that the user can turn on (which involves looking for sets of rows that meet a certain criterion, and then marking rows visible or not based on the results) that MUST be applied logically after all the other filters (i.e. it does share 'commutative property' as all the column-top filters do). This extra analysis/filter step intends to take the row set that is produced by the column-top filters and then apply this one final, mother-of-all-complex-filtration steps.
I am able to get that filtration logic to produce initially correct results - when the user first clicks into the special mode, I perform the analysis and save the necessary info in a hidden column of the grid; and then a RowsProcessor sets the row.visible attribute accordingly. (perhaps I didn't need the RowsProcessor, and maybe I could have just set the visibility in the analysis subroutine.) But whatever - the point is that the rows are marked visible or not. The problem occurs when the user subsequently adds/removes/changes a filter to one of the column top filters. That extra analysis step by necessity needs to be based upon the rows that are visible according to the column-top-filters. And the first time into the special filtering routine, a call to gridApi.core.getVisibleRows() returns exactly that rowset. But after that, the visible rowset is now reduced by the prior execution of the special filtering. But I need to get back to the rowset (i.e. complete recalculation of the row.visible attributes) of just the column-top-filters, without any special final filtration. Is there a way to do that - to effectively undo the filtration effects of the RowsProcessor?
Short version of the question
Is there some way to force recalculation of the visible row set based on the column top filters? and to do so in a way to get control back so additional filtration steps can be executed?
I've looked at various things in the APIs but cannot tell which, if any, might help me. For example:
In the ui.grid (Grid) portion of the API, I see many different flavors of refresh methods that may help, but there's no distinction given that I understand. I hope the one that I need is not refreshRows( ) that says "not functional at present"
Also, the GridRow 'class' seems to have various methods that speak of
visibility "overrides" - that sounds possibly like what I might need
(my final visibility result possibly being an override to those calculated by the column-top filters). But I tried using those methods instead of directly setting row.visible and I did not see any difference.
Can anyone suggest a direction for me to try?
and even better, is there any written description that provides a high-level overview of ui-grid functionality? I love the package, but using it for the first time, I'm just having a hard time with what are probably basic concepts, and possibly I'm thinking about this problem all wrong.
Once again, thanks for any assistance.
Whenever the rowsProcessors run they start by setting all rows to visible, then each rowsProcessor runs in turn with the results from the previous rowsProcessor being passed to the next one. RowsProcessors have a priority, so you can set your processor to run at the appropriate place in the sequence.
It sounds like your problem is that you're using getVisibleRows to calculate what to do, rather than looking at the rows that are passed in to your rows processor, and evaluating based on which rows are visible in that input.
My guess is that you would be better to set your rowsProcessor to have a high (late) priority, and then process all your calculations within that processor rather than attempting to cache them on the data set itself. If you need to extract the visible rows from the set of renderableRows that are passed to your processor, you could do it with:
var visibleRows = renderableRows.filter( function(row) { return row.visible; });

Use Reactive Extensions to harmonize & simplify Control.Enabled = true/false conditions?

Is it possible, or more precisely how is it possible to use RX.Net to listen to a number and different variety of (WinForms) controls' .TextChanged/.RowsChanged/.SelectionChanged events and whenever one condition is fullfilled (ControlA.Text isn't empty, ControlB.RowsCount > 0 etc) enable that one DoSomething button.
I am asking because currently we have a lengthy if/then statement in each of these events' handlers and maintaining them if the condition changes is, due to duplicate code, quite error prone and that's why, if possible, I think it would be nice to take the stream of events and put the condition in one place.
Has anyone done that?
You can use Observable.FromEventPattern in combination with Join patterns, with Observable.When, Observable.And and Observable.Then, to create observables which will fire depending on various conditions, like combinations of events. For example, consider my answer here: Reactive Extensions for .NET (Rx): Take action once all events are completed
You should be able to use .FromEventPattern() to create observables for each of those events and then use CombineLatest() to do your logic on the current overall state and determine whether your button should be enabled, in one place.

When does the defered execution occur?

I've got a situation which I want to fetch data from a database, and assign it to the tooltips of each row in a ListView control in WPF. (I'm using C# 4.0.) Since I've not done this sort of thing before, I've started a smaller, simpler app to get the ideas down before I attempt to use them in my main WPF app.
One of my concerns is the amount of data that could potentially come down. For that reason I thought I would use LINQ to SQL, which uses deferred execution. I thought that would help and not pull down the data until the user passes their mouse over the relevant row. To do this, I'm going to use a separate function to assign the values to the tooltip, from the database, passed upon the parameters I need to pass to the relevant stored procedures. I'm doing 2 queries using LINQ to SQL, using 2 different stored procedures, and assigning the results to 2 different DataGrids.
Even though I know that LINQ to SQL does use deferred execution, I'm beginning to wonder if some of the code I'm writing may defeat my whole intent of using LINQ to SQL. For example, in testing in my simpler app, I am choosing several different values to see how it works. One selection of values brought no data back, as there was no data for the given parameters. I thought this could potentially cause the user confusion, so I thought I would check the Count property of the list that I assign from running the DBML associated method (related to the stored procedure). Thinking about it, I would think it would be necessary for LINQ to run the query, in order to give me a result for the Count property. Am I not correct?
If I eliminate the call to the list's Count property, I'm still wondering if I might have a problem; if LINQ may still be invoked, because I'm associating the tooltip to the control via a function call?
You are correct, when you call the Count property it iterates over the result set. Not clear on your last question, but the LINQ probably gets called at the point where you populate your DataGrids, way after the tooltip comes into play.
EDIT: however, this does not mean there is anything wrong with deffered execution or your use of it, it executes at the latest possible stage, right when you need the data. If you still want to check the Count ahead of actually fetching all the data, you could have a simple LINQ to SQL function that checks for Any() rows. (Actually Any() is probably what you want more than Count > 0)
You should use Any(), not Count(), but even Any() will cause the query to be executed - after all, it can't determine whether or not there are any rows in the result set without executing the query. But there's executing the query, and there's fetching the result set. Any() will fetch one row, Count() will fetch them all.
That said, I think that having a non-instantaneous operation that occurs on mouseover is just a bad idea. There was a build of Outlook, once, that displayed a helpful tooltip when you moused over the Print button. Less helpfully, it got the data for that tooltip by calling the system function that finds out what printers are available. So you'd be reaching for a menu, and the button would grab the mouse pointer and the UI would freeze for two seconds while it went out and figured out how to display a tooltip that you weren't even asking for. I still hate this program today. Don't be this guy.
A better approach would be to get your tooltip data asynchronously after populating the visible data on the screen. It's easy enough to create a BackgroundWorker that fetches the data into a DataTable, and then make the DataTable available to the view models in the RunWorkerCompleted event handler. (Do it there so that you don't do any updates to UI-bound data on the UI thread.) You can implement a ToolTip property in your view model that returns a default value (probably null, but maybe something like "Fetching data...") if the DataTable containing tool tip data is null, and that calculates the value if it's not. That should work admirably. You can even implement property-change notification so that the ToolTip will still get updated if the user keeps the mouse pointer over it while you're fetching the data.
Alex is correct that calling Count() or Any() will enumerate the LINQ expression causing the query to execute. I would recommend re-thinking your design as you probably don't want a query to the database executed every time the user moves his/her mouse. There is also the issue of the delay to query the database. What might be instantaneous on your dev box with a local database might have a multi-second delay on a heavily loaded server. I would recommend creating a DisplayTooltip() function that takes a lazily evaluated LINQ expression. You can then cache the results or apply other heuristics to decide whether you should actually be querying the database or not.

How to avoid a series of "if" statements?

Assume, I have a form ...lets say WinForm... with 'n' number of controls.
I populate them with a default value during the LOAD. Then, the user gets to play with all the controls and set different values for the controls and submit the form. Here is where I find myself writing a series of "if" conditional statements handling the value of each of the controls for (but not restricted to) avoiding nulls, doing validation etc.
Though it works, is there some other more efficient way of doing this instead of disparate "ifs" ?
You may not avoid the 'ifs' entirely, but sometimes it helps to gather related bunch of controls on your Form into User Controls. Then you can move the validation and all from the Form class into individual User Controls, thus reducing clutter.
You should know that WinForms has build in facilities for both validation and data binding. Using these built-in capabilities will definitely result in code that is better structured and easier to write and maintain than hand coding data and validation operations. Beth Massi has done a series of videos that demonstrates these features, you can find them on the MSDN web site.
** Edited **
I don't have a catch-all, as this will vary from form to form, but some general advice.
By the way, I love this question because it's all about keeping your code clean, readable, and doing things as simply as possible.
Use the included validation controls when possible rather than writing if statements to validate code. (see instruction video for winforms (based on the question I'm assuming you mean .Net winforms.) here)
Always look to see if you can write a function to handle repetitive tasks. It takes a line of code to call a function, and if your function is only fivelines long, but you call it tentimes, that means you've saved yourself a lot of duplicate lines of code.
If you can write that function to be smart enough and be able to loop through your controls, so much the better.
In short, look at your code and determine to try to do the job with the least amount of code possible while making it easily readable and understandable, and without resorting to bad practices. Experiment in your spare time on non-production "test" code to refine your technique as you learn, but if you get used to thinking about clean code you get better at writing it.
Create a set of Validators to match 1-for-1 with your controls. Derive from the base Validator a ControlXValidator, which take a ControlX as its constructor, and implements isValid() in the special way that ControlX must evaluate as valid, and implements getDiagnosticMessage to display an appropriate message if the validation fails. Then at the end of your form construction code, create a list of Validators containing the Validator subclass for each control.
Then your validateForm() method can just do something like:
allvalid = True;
foreach(Validator vtor in allValidators)
{
if (!vtor.isValid())
{
StatusBar.Caption = vtor.getDiagnosticMessage();
allvalid = False;
break;
}
}
If you are validating by data-type (dates should look like dates), you could use a function that validates your data and pass the function both the user input and a "sample" of valid data. Valid samples could be stored in an array, keyed by the data-type.
And if the data is not valid, the function returns false and you have one if statement that says "if function returns false, punch the user".
Assume a decently strong language:
Create a hash (a.k.a Map) with the keys as the control identities and the values as functions. Retrieve the function and call.
restrict your control.....life in text box you can set limit of inputr chars ...etc....
not specific to any language: use Guard Clauses is usually a good way to get rid ifs. It is a excellent way to check nulls and validations.

Resources