simple problem, but perhaps no simple solution, at least I can’t think of one of the top of my head but then I’m not the best at finding the best solutions.
I have a stored proc, this stored proc does (in a basic form) a select on a table, envision this:
SELECT * FROM myTable
okay, simple enough, except the table name it needs to search on isn’t known, so we ended up with something pretty similiar to this:
-- Just to give some context to the variables I'll be using
DECLARE @metaInfoID AS INT
SET @metaInfoID = 1
DECLARE @metaInfoTable AS VARCHAR(200)
SELECT @metaInfoTable = MetaInfoTableName FROM MetaInfos WHERE MetaInfoID = @MetaInfoID
DECLARE @sql AS VARCHAR(200)
SET @sql = 'SELECT * FROM ' + @metaInfoTable
EXEC @sql
So, I, recognize this is ultimately bad, and can see immediately where I can perform a sql injection attack. So, the question is, is there a way to achieve the same results without the construction of the dynamic sql? or am I going to have to be super, super careful in my client code?
You have to use dynamic sql if you don’t know the table name up front. But yes, you should validate the value before attempting to use it in an SQL statement.
e.g.
This will make sure a table with that name exists. There is an overhead to doing this obviously as you’re querying INFORMATION_SCHEMA. You could instead validate the @metaInfoTable contains only certain characters: