I load my INFORMATION_SCHEMA.TABLES into a listbox. I let the user select table, then in the listbox next to it the columns for this table appear. I simply get the talbe name like this:
tableName = lbTables.GetItemText(lbTables.SelectedItem);
now to get the columns, this works:
SqlCommand allTables = new SqlCommand("SELECT * FROM "+tableName+";", conn);
and this doesn't work:
SqlCommand allTables = new SqlCommand("SELECT * FROM @0;", conn);
allTables.Parameters.AddWithValue("@0", tableName);
Secondly I try to insert a new row into the same table:
SqlCommand comm = new SqlCommand("INSERT INTO [dbo.][@0] (@1) VALUES ('@2')",conn);
comm.Parameters.AddWithValue("@0", tableName);
comm.Parameters.AddWithValue("@1", columnName);
comm.Parameters.AddWithValue("@2", someValue);
Again, hardcoriding tableName
and 'columnName' works.
For the tableName I've tried this:
SqlParameter typeTable = comm.Parameters.AddWithValue("@0", tableName);
typeTable.SqlDbType = SqlDbType.Structured;
typeTable.TypeName = "dbo." + tableName;
But that gave me the error: Must declare the table variable @0
I'm kind of spending to much time on this problem right now and I have not find the right answer yet, i'll keep searching though...
EDIT: After some comments it turns out that I was not aware that parameters can only be used for VALUES in INSERRT/UPDATE and WHERE clauses. So I am looking for a 'SQL injection safe' method to dynamically choose a table and column.
Table names need to be static. You cannot pass a variable as the table name in SQL:
Use this:
SqlCommand comm = new SqlCommand(String.Format("INSERT INTO [dbo][{0}] ({1}) VALUES ('@val')", tableName, columnName),conn);
comm.Parameters.AddWithValue("@val", someValue);
In SQL, you can achieve this with sp_executesql
:
declare @query nvarchar(4000) = 'INSERT INTO [dbo][' + @tableName + '] (' + @columnName + ') VALUES (@p)'
declare @Params nvarchar(500) = '@v nvarchar(10)'
execute dbo.sp_executesql @query, @params, @p = 'someValue'
But you need to be very carefull with this and check your tableName
and columnName
variables to avoid SQL Injection.