views:

46

answers:

2

How do I pass and use the column name to retrieve a bigint variable in the actual column?

DECLARE @personID BIGINT,
DECLARE @queryString varchar(500)

Set @queryString = 'Select @personID = ' + @PersonColumnID + ' from dbo.Loss_Witness where WitnessID = @witnessID'
exec(@queryString)

Error message states "Must declare variable '@personID'." I also tried

Set @queryString = 'Select ' + @personID + ' = ' + @witnessPersonID + ' from dbo.Loss_Witness where WitnessID = @witnessID'

And got the error message "Error converting data type varchar to bigint."

Any thoughts?

+6  A: 

You need to specify that @personID is an out parameter with the OUTPUT keyword:

DECLARE @SQL NVARCHAR(max)
    SET @SQL = 'SELECT @personID = w.' + @PersonColumnID + ' 
                  FROM dbo.Loss_Witness w
                 WHERE w.witnessID = @witnessID '

BEGIN 

  EXEC sp_executesql @SQL, @personID = @personID OUTPUT, @witnessID

END

There's another example here.

OMG Ponies
+1  A: 

Also note that there is potentially an SQL Injection security hole in your code. If you're not sanitizing @PersonColumnID then you could be in big trouble.

Yellowfog
@OMG Ponies There is still a risk here, even if slight: column names can not be passed as parameters to sp_executesql and thus the reason for the concatenation in the input (but note that the values are parametrized).
pst
I'm struggling to understand this comment. The paper you cite is excellent, and a standard read on dynamic SQL. But regardless of that, there is a huge SQL Injection point in the code given and in your rewrite, unless @PersonColumnID is sanitized. It was possible that the questioner wasn't aware of this.
Yellowfog
SELECT @PersonColumnID = '1; drop database blah --' ;
Yellowfog