我将INFORMATION_SCHEMA.TABLES加载到列表框中。我让用户选择表,然后在它旁边的列表框中显示该表的列。我只是得到这样的talbe名称:
tableName = lbTables.GetItemText(lbTables.SelectedItem);
现在获取列,这有效:
SqlCommand allTables = new SqlCommand("SELECT * FROM "+tableName+";", conn);
这是行不通的:
SqlCommand allTables = new SqlCommand("SELECT * FROM @0;", conn);
allTables.Parameters.AddWithValue("@0", tableName);
其次,我尝试在同一张表中插入新行:
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);
同样,hardcoridingtableName
和'columnName'可以工作。
对于tableName,我已经尝试过了:
SqlParameter typeTable = comm.Parameters.AddWithValue("@0", tableName);
typeTable.SqlDbType = SqlDbType.Structured;
typeTable.TypeName = "dbo." + tableName;
但这给了我一个错误:Must declare the table variable @0
我现在在这个问题上花了很多时间,但是我还没有找到正确的答案,尽管如此,我还是会继续寻找...
编辑:经过一番评论后,我发现我不知道参数只能用于INSERRT / UPDATE和WHERE子句中的VALUES。因此,我正在寻找一种“ SQL注入安全”方法来动态选择表和列。
表名必须是静态的。您不能在SQL中将变量作为表名传递:
用这个:
SqlCommand comm = new SqlCommand(String.Format("INSERT INTO [dbo][{0}] ({1}) VALUES ('@val')", tableName, columnName),conn);
comm.Parameters.AddWithValue("@val", someValue);
在SQL中,您可以使用以下方法实现此目的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'
但是您需要对此非常谨慎,并检查您的tableName
和columnName
变量,以避免SQL注入。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句