tags:

views:

313

answers:

3

Unfortunately I don't have a repro for my issue, but I thought I would try to describe it in case it sounds familiar to someone... I am using SSIS 2005, SP2.

My package has a package-scope user variable - let's call it user_var

  1. first step in the control flow is an Execute SQL task which runs a stored procedure. All that SP does is insert a record in a SQL table (with an identity column) and then go back and get the max ID value. The Execute SQL task saves this output into user_var
  2. the control flow then has a Data Flow Task - it goes and gets some source data, has a derived column which sets a column called run_id to user_var - and saves the data to a SQL destination

In most cases (this template is used for many packages, running every day) this all works great. All of the destination records created get set with a correct run_id.

However, in some cases, there is a set of the destination data that does not get run_id equal to user_var, but instead gets a value of 0 (0 is the default value for user_var).

I have 2 instances where this has happened, but I can't make it happen. In both cases, it was just less that 10,000 records that have run_id = 0. Since SSIS writes data out in 10,000 record blocks, this really makes me think that, for the first set of data written out, user_var was not yet set. Then, after that first block, for the rest of the data, run_id is set to a correct value.

But control passed on to my data flow from the Execute SQL task - it would have seemed reasonable to me that it wouldn't go on until the SP has completed and user_var is set. Maybe it just runs the SP, but doesn't wait for it to complete?

In both cases where this has happened there seemed to be a few packages hitting the table to get a new user_var at about the same time. And in both cases lots of data was written (40 million rows, 60 million rows) - my thinking is that that means the writes were happening for a while.

Sorry to be both long-winded AND vague. A winning combination! Does this sound familiar to anyone? Thanks.

Updating to show the SP I use to get the user_var:

CREATE PROCEDURE [dbo].[sp_GetRunIDForPackage] (@pkg varchar(50)) AS

-- add a new entry for this run of this package - the RUN_ID is an IDENTITY column and so 
-- will get created for us
    INSERT INTO shared.STAGE_LOAD_JOB( EFFECTIVE_TS, EXECUTED_BY ) 
    VALUES( getdate(), @pkg )

-- now go back into the table and get the new RUN_ID for this package
SELECT MAX( RUN_ID )
    FROM shared.STAGE_LOAD_JOB
     WHERE EXECUTED_BY = @pkg 
A: 

Did you check the value of user_var before getting to the Derived Column Component? It sounds like user_var may be 0 so you are doing run_id = user_var; run_id = 0. I may be naive to think it is that simple but that's the first thing I would check.

ajdams
Before my problematic DFT, there is actually another (auditing) DFT that also makes use of **user_var**. It always succeeds in writing out a non-zero value from **user_var**. This makes me believe that **user_var** has a non-zero value. Maybe the difference is because the main (problematic) DFT writes out lots of data, and the audit DFT is quick? But the audit DFT comes first! So weird.
soo
A: 

Given the procedure code, you might want to replace this:

SELECT MAX( RUN_ID ) FROM shared.STAGE_LOAD_JOB WHERE EXECUTED_BY = @pkg

with this:

select scope_identity()

The scope_identity() function returns the identity that was entered in the current scope, which is the procedure. Not sure if this will solve the problem, but I find it best to work through them all as they might have unrelated consequences.

Josef Richberg
@Josef - added the code for the SP to my original post
soo
@Josef - thanks, I did think of using scope_identity, and it is certainly something to try. My gut feeling though is that *user_var* is getting set just fine, but that sometimes its value is inaccessible (similar to Ben's experience). Definitely appreciate the input.
soo
+3  A: 

Is this variable being accessed lots of times, from lots of places? Do you have a bunch of parallel data flows using the same variable?

We've encountered a bug in both SQL 2005 and 2008 whereby a "race condition" causes the variable to be inaccessable from some threads, and the default value is used. In our case, the variable was our "base folder" location for packages, causing our overall execution control package to not find its sub-packages.

More detail here: http://stackoverflow.com/questions/1779767/ssis-intermittent-variable-error-the-system-cannot-find-the-file-specified/2878108#2878108

Unfortunately, the work-around is to hard-code a default value into the variable that will work when the race condition happens. Easy for us (set base folder to be correct for our prod environment), but looks a lot hard for your issue.

Perhaps you could use multiple variables (one for each data flow), and a bunch of Execute SQL tasks to populate those variables? REALLY ugly, but it should help.

Ben Gracewood
I should add, the condition was incredibly intermittent and hard to reproduce, but happened regularly, from different packages, at different times. Took a 2GB full stack trace for Microsoft Support to locate it.
Ben Gracewood
Hey Ben, thanks - this sounds like a very similar effect, though I must have some difference cause as I don't have parallel dataflows accessing the var. I do have multiple DFTs accessing the variable, but in an ordered sequence. Still sounds like a useful hint... I don't supposed there is a way to *set* a var and *then* make it read-only, is there? If there was, no doubt that would have been a good solution in your situation.
soo
Readonly/ReadWrite is not a variable attribute, but how you access it. I can have one process access the variable as readwrite, but others access it as read only. To avoid this, I usually keep each DFT with it's own variables to prevent them from stepping on each other's toes. There is a consideration where you have multiple paths in a DFT and each result sets a variable to a different value. What I found was you cannot predict which path is last, so the value might be overwritten. I have blogged about it. http://josef-richberg.squarespace.com/journal/2010/5/1/ssis-data-flow-paths.html
Josef Richberg

related questions