我正在尝试在C#中针对SQL Server数据库创建参数化查询。
代码:
query = new StringBuilder( "SELECT @fields FROM @tables");
using(SqlConnection connection = new SqlConnection(connection))
{
SqlCommand command = new SqlCommand(query.ToString(), connection);
command.Parameters.AddWithValue("@fields", fields.ToString());
command.Parameters.AddWithValue("@tables", tables.ToString());
try
{
connection.Open();
Int32 rowsAffected = command.ExecuteNonQuery();
Console.WriteLine("RowsAffected: {0}", rowsAffected);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
奇怪的部分是失败,并显示消息“必须声明表变量”@ tables \“。但是正如您所看到的,它已被明确定义。
所以我的问题是:
答案 0 :(得分:7)
SQL不支持参数化FROM子句。因此,您必须使用动态SQL,或者在将查询字符串提交到数据库之前创建/连接查询字符串。
答案 1 :(得分:2)
不幸的是,您无法在FROM子句中使用参数。
答案 2 :(得分:1)
我认为这不是SQL命令及其参数的样子。它应该看起来像
SELECT fieldName1, fieldName2
FROM TableName
WHERE fieldName = @paramName
您不能将参数用作要选择的字段的定义或目标表。如果需要定义要选择的字段,只需在调用它之前在StringBuilder中编写命令字符串 - 根据需要。参数用于过滤目的。在您的情况下,您不需要任何参数,只需构建您的命令并执行。
答案 3 :(得分:0)
如果您确信表和列名称正常,那么在构建动态SQL之前,您可以在数据库中进行一些安全检查。
这只是为了说明 - 对于现实生活,显然你需要让它更清洁:
declare @TABLE_NAME nvarchar(128)
set @TABLE_NAME = 'Robert'');DROP TABLE Students;--' -- This line will raise an error
set @TABLE_NAME = 'BOOK' -- This line will go through properly
declare @sql varchar(max)
set @sql = 'SELECT * FROM '
if exists (select 1 from sys.objects where type = 'U' and name = @TABLE_NAME)
begin
set @sql = @sql + @TABLE_NAME
exec (@sql)
end
else
begin
raiserror ('ERROR ERROR ERROR', 0, 0)
return
end