views:

1467

answers:

5

I'm trying to write a stored procedure and depending on a certain column value, I want to be able to change what table I select from. I'll try to give an example:

SELECT ItemNumber,
       ItemType, 
       Description
FROM

CASE ItemType
WHEN 'A' THEN TableA
ELSE TableB
END

WHERE 

CASE ItemType
WHEN 'A' THEN ItemNumber = @itemNumber
ELSE PartNumber = @itemNumber
END

As you can see, not only am I dynamically changing the table I select from, but since these two tables were made at two different times by two different people, the column names are different as well.

So, my question is: What is the best way to accomplish this, since SQL Server doesn't seem to like my query I have constructed.

If anyone who sees what I'm trying to do can suggest a better way to do this, I'd be all ears :-)

A: 

You are better of using UNION query to join the tables first, and then SELECT.

Also, you may consider creating a view for one of the tables, so it pulls only the columns you need while renaming them, then UNION, and then select from the UNION.

Or use a temp table to store the result from each query. Put the creation of the temp table in a CASE (pseudocode, not tested):

CASE @itemType
   WHEN 'A'
      SELECT ACol1 AS Col1, ACol2 AS Col2
      FROM TABLE_A
      INTO #tempTable
      WHERE ItemNumber = @itemNumber
   ELSE
      SELECT BCol1 AS Col1, BCol2 AS Col2
      FROM TABLE_B
      INTO #tempTable
      WHERE PartNumber = @itemNumber
END

SELECT * FROM #tempTable
Sunny
+2  A: 

You could try building the dynamic SQL statement as a string, and then calling the sp_executesql stored procedure to execute the string.

See here for more information and examples.

axel_c
I doubt that dynamic SQL is really necessary here unless the schema is even more pathological.
Cade Roux
I agree the SP has really bad design, but I think this is the easiest solution to the proposed problem.
axel_c
I don't think the problem is specified solidly enough to determine that it can't be solve with basic SQL first. Dynamic SQL should not be considered in general until the obstacle to ordinary SQL indicate it is the correct choice.
Cade Roux
+1  A: 

You really aren't explaining where ItemType is coming from. As suggested UNION might be applicable if you are simply combining two tables.

Here's another possibility which may relate to your problem:

SELECT ItemNumber,
       ItemType, 
       COALESCE(TableA.Description, TableB.Description) AS Description
FROM Items
LEFT JOIN TableA
    ON Items.ItemType = 'A'
    AND TableA.ItemNumber = Items.ItemNumber
LEFT JOIN TableB
    ON Items.ItemType <> 'A'
    AND TableB.ItemNumber = Items.ItemNumber
Cade Roux
A: 

You can not use CASE statement in FROM clause, but you can use the following instead:

SELECT itemnumber, itemtype, description
  FROM tablea
 WHERE itemnumber = @itemnumber AND itemtype = 'A'
UNION ALL
SELECT itemnumber, itemtype, description
  FROM tableb
 WHERE partnumber = @itemnumber AND itemtype <> 'A'
I meant FROM clause
+2  A: 

I'm not sure why you want to do things in one SQL Statement .. I'm not a SQL Server person, but in an Oracle stored procedure you could write something like this

If itemtype = 'A' 
Then 
 <statement for table A>
Else
 <statement for Table B>
End if

Something like this should work in SQL Server, too .. maybe someone could expand on this?

IronGoofy
Thats what I would do as well
HLGEM