I'm currently working on a data API and I would like to generate an SQL query based on the requested field names. Those field names will be publicly available and the users will also be able to use alias to rename the data returned by the API.
The records available in those tables won't be filed as "top secret" but I still want to prevent any SQL injection by using a parametrized field name and alias to avoid people from adding unwanted data.
DECLARE @requestedFieldName NVARCHAR(max) = 'FirstName';
DECLARE @alias NVARCHAR(max) = 'First name';
SELECT @requestedFieldName AS @alias FROM MyTable
There's plenty of examples using parameters in WHERE clauses and other clause involving a value to be matched/assigned/set with a field... however, I couldn't find any example involving a parametrized field name / alias in SQL server (there's some SO question about JDBC and MySQL but none with SQL Server)
Is there a way to parametrized a field name or should I consider building an intermediate interface that will hold the list of every available fields a user can request? (I know the second option is used a lot but we have A LOT of table and their structure will change on a regular basis).
Use
varchar
parameters to get the columns list and the table name.Then check the values of those parameters against the
sys.columns
table.If all columns match then you can safely use the values to create a dynamic SQL and execute it. If you also need the user to pass the conditions to build the where clause, do the same test for the columns there.
Update Now that I've created a sample code, I think that this is probably not the best solution for you, unless you can find a way to dynamically create the stored procedure for each table. The reason for this is the where clause, and the fact that each table have a different number of columns with different data types, making the creation of the where clause parameter list very table dependent. (and actually, the creation of the number of the select parameters is also dependent on the table).
Therefore, I'm not sure that this is a practical solution, but it was a fun t-sql challenge for me Nevertheless, I've already created the code sample, and perhaps someone will find a way to use such a procedure, so I'll share it:
First, DDL for a sample table:
and a sample for a safe dynamic sql stored procedure:
And of course, a sample execute code:
And the result of all this mess is this:
You can get the columns list for each table to your c# code and build the dynamic query there. it would probably be a shorter and faster code.