As I get more and more educated on SSIS, I’m becoming more appreciative of what it does (or in some cases, intends to do) overall but I’m also finding some of the weirdest things that are just a little “off”. Most are just the kind of things that make you go “huh, that’s strange”, but I found one yesterday that made me seriously stop and scratch my head because I was just completely lost as to why things would be done this way. In fact, if it weren’t for the Wrox SSIS book
that I got, I probably wouldn’t have figured out the answer.
I’ll start this off with a quick question for you to ponder the answer to before I go into the details — What is a “property” on an object other than essentially just a variable defined only within the scope of that object? Rather than answer that question just yet, here’s the problem I was scratching my head over. In SSIS, they have some nifty pre-defined events which you can easily attach event handlers to. Thanks to Jamie Thomson’s blog post entitled “Custom Logging Using Event Handlers” I’ve been happily coding away logging routines using the OnPreExecute and OnPostExecute event handlers (among a few others). But, I soon ran into a problem that wasn’t addressed in the blog post, and that was that every event that fires propagates up the call chain, regardless of whether or not the event is handled[*]. That is to say, if I have an SSIS package that has (”contains”) a task which loads a file into a database, and I define an event handler for OnPreExecute that simply writes a row to an event log that says “Started: “, then once it gets to the file load task, the database will contain the following:
- Started: Main package
- Started: File load
- Started: Main package
Obviously that last row is a bit silly because the main package didn’t just start, it’s in the middle of executing all of its tasks. That’s because the PreExecute event propagated up from the file load task. Now, one might argue that propagating that particular event doesn’t make a lot of sense because you only ever PreExecute once for each task, and it certainly has nothing to do with when the child tasks do anything. But, for the sake of consistency I can forgive that. If that was the wart, then that’d just be a “huh, thats strange” kind of wart. After all, you certainly do want Error and Warning events to propagate up so you can just define event handlers for those in the parents.
So, at this point I figure there has to be some way to prevent the upward propagation of some events, even if I have to specify it per event handler. The first place I looked was in the properties for the event handler. The only thing that looked mildly promising was the LoggingMode property, but that was limited to “Use Parent Setting”, “Enabled”, or “Disabled” - nothing about “handle and stop propagating”. So, the next place I checked was the “expressions” for the event handler. Expressions in SSIS are basically ways of setting properties that are dynamic (ie, can change at/during runtime), and they’re very useful and generally contain most of the properties anyway, plus an occasional extra tidbit. Well, no extra helpful tidbits in this case, though I was positive that was where it would be.
What does any good programmer do when they’ve exhausted their available local resources? Google it, of course. Unfortunately no matter what search string I used (and my Google-fu is pretty good), I couldn’t find anything that would tell me how to do what I want. Plus, the only other SME on SSIS in the company that I’m aware of was unavailable to ask, and I’m about to outgrow using him as a reference anyway. Then I remembered the aforementioned book, and sure enough one of the first things in the index under events was “bubbling”. And in less than 2 minutes of reading, I had my solution.
Now for the solution and then a quick revisit to the question I kicked this story off with. The solution: there is a “system variable” defined at the error handler scope level entitled Propagate, which if you set it to False will not propagate the event to its parent(s). How the heck is a system variable defined only within the scope of a single object (and obviously only useful within that scope) a better choice than a property? Properties are displayed in a nice little grid that’s easily accessible. System variables are hidden behind several clicks in the interface. I’d wager that 95% or more of SSIS packages never have to muck about with them, and none of the dozen or more packages I’ve worked on have ever needed to do so (until now!), in spite of all the functionality I’ve included. Thankfully, I’m not the only one who had such an issue (I didn’t find that blog post until I started writing this one, and he doesn’t have the solution in his post, but Jamie Thomson posted a response which he found).
And to make matters worse I just realized that this means I’ll have to define that variable for all children within a package otherwise I’ll get a lot of “Started: Main package” messages, one for each sub-task (which is a lot, including checking for input, truncating tables, etc.). According to the blog post and response linked at the end of the last paragraph, there’s no way to tell an event handler to not listen to propagated events either. Sigh.
[*] - it also doesn’t help that Microsoft’s documentation has a very misleading/incorrect diagram showing event propagation stopping at the first handled event