我正在试验如何允许Web应用程序支持多个数据库,特别是SQL Server和MySQL。
我已经设置了我的SQL帮助程序类,它将负责连接数据库和查询执行。我正在使用IDBCommand
,IDBConnection
等。我已经使用控制台应用程序测试了这个类,它可以很好地处理没有参数的查询。
但是当我添加参数时,就是问题开始的地方。
我希望使用表名的参数,因为当前的表名可能会更改,重命名查询中的表会很痛苦。
我发现了一篇文章,作者分享了他向IDBCommand
添加参数的方法。我找不到文章的链接,但这里是我从文章中得到的一个样本(感谢作者btw!:D)我能够确认参数被添加,因为它们被列在{{ 1}}通过使用QuickWatch但我得到一个“必须声明表变量”@myTable“。”错误。
IDBCommand
对我做错了什么的想法?
编辑:
在回复bew的回复时,我能够使用 internal static int AddInputParameter<T>(this IDbCommand cmd,
string name, T value)
{
var p = cmd.CreateParameter();
p.ParameterName = name;
p.Value = value;
return cmd.Parameters.Add(p);
}
和SqlCommand
执行此操作。
EDIT2:
看起来我记得错了。我在过去的项目中使用MySqlCommand
作为表名。
答案 0 :(得分:4)
简短的回答是您不能将表作为参数传递。相反,在运行时确定表的任何查询必须在用于参数化查询之前组合为字符串。更长的答案需要了解当您使用参数化动态SQL语句调用cmd.ExecuteReader
之类的内容时会发生什么。在这种情况下,.NET类使用sp_executesql
构建一个调用。例如:
Declare @Sql nvarchar(max);
Set @Sql = 'Select Count(*) From sys.objects Where object_id > @SomeNum';
exec sp_executesql @Sql, N'@SomeNum int', 10000;
现在假设我们尝试将表的参数插入到SQL语句中。结果陈述将是:
Declare @Sql nvarchar(max);
Set @Sql = 'Select Count(*) From @SomeTable Where object_id > @SomeNum';
exec sp_executesql @Sql, N'@SomeTable nvarchar(256),@SomeNum int', 'sys.objects', 10000;
这将导致Must declare the table variable "@SomeTable"
行的错误。 SQL Server不知道@SomeTable
是一个参数而不是表变量。因此,对象引用(表,视图,过程等)不是可以参数化的东西;只有标准可以参数化。
答案 1 :(得分:1)
我不知道这是否会有所帮助,但这是我前一段时间使用过的功能。它使用匿名类型来添加参数。随意将其用作模板:
private static void Addparms(SqlCommand cmd, object parms)
{
// parameter objects take the form new { propname = "value", ... }
foreach (PropertyInfo prop in parms.GetType().GetProperties())
{
cmd.Parameters.AddWithValue("@" + prop.Name, prop.GetValue(parms, null));
}
}
然后像这样调用:
Addparms(cmdObject, new { name = "Hogan", page = 1, last = "Long" });
这将添加3个参数@name
,@page
和@last
。