此查询产生错误No value given for one or more required parameters
:
using (var conn = new OleDbConnection("Provider=..."))
{
conn.Open();
var result = conn.Query(
"select code, name from mytable where id = ? order by name",
new { id = 1 });
}
如果我将查询字符串更改为:... where id = @id ...
,我将收到错误:Must declare the scalar variable "@id".
如何构造查询字符串以及如何传递参数?
答案 0 :(得分:12)
当前的源代码(尚未发布到NuGet)解决了这个问题;以下应该有效:
var result = conn.Query(
"select code, name from mytable where id = ?id? order by name",
new { id = 1 });
答案 1 :(得分:7)
在当前构建中,答案是“否”,原因有两个:
@id
,:id
或?id
之类的内容好消息是这两个都是可以修复的
对我的本地克隆进行这些更改后,现在传递以下内容:
// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
using (var conn = new System.Data.OleDb.OleDbConnection(
Program.OleDbConnectionString))
{
var row = conn.Query("select Id = ?, Age = ?", new DynamicParameters(
new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
) { RemoveUnused = false } ).Single();
int age = row.Age;
int id = row.Id;
age.IsEqualTo(23);
id.IsEqualTo(12);
}
}
请注意,我目前正在使用DynamicParameters
来避免向Query
/ Query<T>
添加更多重载 - 因为这需要添加到相当多的方法中。将其添加到DynamicParameters
可以在一个地方解决它。
在我推动之前,我愿意接受反馈 - 这看起来对您有用吗?
编辑:添加了一个时髦的smellsLikeOleDb
(不,不是笑话),我们现在可以更直接地做到这一点:
// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
using (var conn = new System.Data.OleDb.OleDbConnection(
Program.OleDbConnectionString))
{
var row = conn.Query("select Id = ?, Age = ?",
new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
).Single();
int age = row.Age;
int id = row.Id;
age.IsEqualTo(23);
id.IsEqualTo(12);
}
}
答案 2 :(得分:0)
我试图在我的软件产品中使用Dapper,该产品使用odbc连接(目前)。然而有一天,我打算放弃使用odbc并使用不同的模式来支持不同的RDBMS产品。但是,我在解决方案实现方面遇到的问题有两个:
与此同时,我已经将一个允许我用Dapper执行此操作的解决方案整合在一起。基本上我有一个例程替换命名参数?并重建参数对象,确保参数的顺序正确。 然而,看看Dapper代码,我可以看到我已经重复了一些dapper正在做的事情,实际上每个参数值现在都被访问了一次,而不是必要的。对于批量更新/插入而言,这变得更加严重。 但至少它似乎对我有用o.k ......
我从here借了一些代码,成为我解决方案的一部分......
答案 3 :(得分:0)
?参数对我来说是解决方案的一部分,但它仅适用于整数,例如ID。对于字符串,它仍然失败,因为未指定参数长度。
OdbcException:错误[HY104] [Microsoft] [ODBC Microsoft Access驱动程序] 无效的精度值
System.Data.Odbc。 OdbcParameter.Bind ((OdbcStatementHandle hstmt, OdbcCommand命令,短序号,CNativeBuffer参数Buffer,bool allowReentrance)
System.Data.Odbc.OdbcParameterCollection.Bind(OdbcCommand命令,CMDWrapper cmdWrapper,CNativeBuffer parameterBuffer) System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior行为,字符串方法,布尔NeedReader,object [] methodArguments,SQL_API odbcApiMethod)
System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior行为,字符串方法,布尔型NeedReader)
System.Data.Common.DbCommand.ExecuteDbDataReaderAsync(CommandBehavior行为,CancellationToken cancelToken)
SqlMapper.Async.cs中的Dapper.SqlMapper.QueryAsync(IDbConnection cnn,Type validType,CommandDefinition命令)
Repository.cs中的WebAPI.DataAccess.CustomerRepository.GetByState(字符串状态)
var result = await conn.QueryAsync(sQuery,new {State = state});
CustomerController .cs中的WebAPI.Controllers.CustomerController.GetByState(字符串状态)
返回等待状态_customerRepo.GetByState(state);
要使Dapper将字符串参数传递给ODBC,我必须指定长度。
var result = await conn.QueryAsync<Customer>(sQuery, new { State = new DbString { Value = state, IsFixedLength = true, Length = 4} });