views:

29

answers:

1

Hi,

I have the following query:

create proc [dbo].GetCustById
as
DECLARE @sql nvarchar(500)
DECLARE @Param  nvarchar(200)
SET @sql = 'select @columnName from customer where custId = @custId'
SET @Param = N'@columnName varchar(10), @custId int'

EXEC sp_executesql @sql, @Param , @columnName = 'Address1', @custId = '42'

But it always return a string "Address1" instead of the value of Address1 column. Anyone can help?

thanks

+1  A: 

A parameter is immediately escaped based on the data type--that's why you're getting the value "Address1" returned rather than the actual value for the column.

Submit the column name not as a parameter, but as a concatenated string:

DECLARE @sql nvarchar(500)
DECLARE @Param  nvarchar(200)
SET @sql = 'select '+ @columnName +' from customer where custId = @custId'
SET @Param = N'@custId int'

EXEC sp_executesql @sql, @Param , @custId = 42

Read more about the behavior here.

The only other alternative I'm aware of requires that you use decision logic to redirect to a query where the column name is statically defined:

IF @columname = 'Address1' 
BEGIN

  SET @sql = 'select Address1 from customer where custId = @custId'

END
OMG Ponies
the reason i cannot make it as concetenate string is because due to security policy. this will open to sql injection!
@user384080: then you are out of luck. You cannot directly parametrise a column name without doing as OMG suggests.
Mitch Wheat
well.. there has to be a better way in doing this out there.. it'll be more than "out of luck" if my app is open to sql injection!
wrong sql injection syntax.. try this: "top 1 * from customer ;drop table customer --"
@user384080: Better example: "'''a'';drop table customer --'", because people are unlikely to know the actual table.
OMG Ponies
haha.. imagine if the table has 20 columns then i will end up with 20 if statements? well.. if it's only 20 columns, what happens if more?
@user384080: I've never worked on an app that needed to fetch single, isolated columns for a particular entity at a time. We'd fetch the entire entity/object, and refresh that as needed.
OMG Ponies
we actually need to pull out an image (binary) from the table and there are 10 image columns. Due to performance issue we cannot pull out all of 10 image columns so we need to prompt the user which image that they wish to load.
anyway.. thanks for ur helps and suggestion.. still looking for the alternative way of doing this out there.
@user384080: Filestream isn't any help? The query would work better if there weren't individual columns for the files. If there was an additional column to indicate which of the 10/etc images to grab....
OMG Ponies