views:

226

answers:

1

I have a number of stored procedures structured similarly to this:

DECLARE @sql NVARCHAR(MAX)
DECLARE @mdx NVARCHAR(MAX)

CREATE table #result
(
  [col1] NVARCHAR(50),
  [col2] INT,
  [col3] INT
)

SET @mdx = '{some dynamic MDX}'
SET @sql = 'SELECT a.* FROM OpenQuery(LinkedAnalysisServer, ''' + @mdx + ''') AS a'

INSERT INTO #result
EXEC sp_executesql @sql
SELECT * FROM #result

This works quite well when results exist in the cube. However, when the OpenQuery results are empty, the INSERT fails with this error:

Column name or number of supplied values does not match table definition.

My question is, what is the best way to handle this scenario? I'm using the results in a static report file (.rdlc), so the explicit typing of the temp table is (I'm pretty sure) required.

+2  A: 

Use TRY/CATCH in your stored procedure, you'll notice there is a specific error number for your problem, so check the error number and if it is that, return an empty result set. As you already have the table defined that'll be easier.

PseudoCode looks something like this:

SET @mdx = '{some dynamic MDX}'
SET @sql = 'SELECT a.* FROM OpenQuery(LinkedAnalysisServer, ''' + @mdx + ''') AS a'

BEGIN TRY

INSERT INTO #result
EXEC sp_executesql @sql

END TRY
BEGIN CATCH

  IF ERROR_NUMBER <> 'The error number you are seeing'
  BEGIN
    RAISERROR('Something happened that was not an empty result set')
  END

END CATCH

SELECT * FROM #result

You'll want to check for that particular error, so that you don't just return empty result sets if your SSAS server crashes for example.

Meff
Just for the sake of completeness, I'll note that the parentheses are required on ERROR_NUMBER(), and that the number returned in this case is 213. My temporary workaround was to remove the NON EMPTY() on my ROWS and COLUMNS axes within the dynamic MDX query, but that wasn't ideal because the empty/sparse tables it was returning were ugly.This works much more nicely, thank you.
Mr. Palomar
Ah yes, thanks for clarifying - I was writing that at home from memory :)
Meff
@MrPalomar, also I used the "Catch/ReThrow" technique explained here: http://stackoverflow.com/questions/1673892/is-there-an-equivalent-in-t-sql-to-cs-throw-to-re-throw-exceptions in order to "Bubble Up" the exception to higher layers, so you can tell if the SSAS server has crashed, or if you have the wring password, or if the query has an error, and so forth.
Meff
Thanks, just ran across this answer and it helped solve a problem I was having.
wshato