带参数的更新命令给出 "Data type mismatch in criteria expression"

Update command with parameters gives "Data type mismatch in criteria expression"

我有以下代码:

/*
// it works
cmd_oper = "UPDATE [Model Elements] SET [Record Status] = \"Disabled\" WHERE [Index] = @db_idx";
/*/
// it doesn't work
cmd_oper = "UPDATE [Model Elements] SET [Record Status] = @stat WHERE [Index] = @db_idx";
//*/
using( OleDbCommand cmd = new OleDbCommand( cmd_oper, svr_conn ) )
{
    cmd.Parameters.Add( "@db_idx", OleDbType.Integer ).Value = 2;
    //cmd.Parameters.Add( "@stat", OleDbType.VarChar ).Value = "Disabled";
    cmd.Parameters.AddWithValue( "@stat", "Disabled" );
    cmd.ExecuteNonQuery();
}

使用 cmd_oper 的第二个变体(代码开头未注释的变体)我得到 "Data type mismatch in criteria expression"。另一个有效。记录状态列的类型在数据库中设置为短文本。我知道 Whosebug 上有很多与此错误相关的帖子,但我找不到完全合适的帖子。谢谢

很好的手册,https://msdn.microsoft.com/en-us/library/system.data.oledb.oledbcommand.parameters(v=vs.110).aspx关于参数有如下说法

The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement or a stored procedure called by an OleDbCommand when CommandType is set to Text. In this case, the question mark (?) placeholder must be used. For example:

SELECT * FROM Customers WHERE CustomerID = ?

Therefore, the order in which OleDbParameter objects are added to the OleDbParameterCollection must directly correspond to the position of the question mark placeholder for the parameter in the command text.

因此,我认为您的代码需要像这样:

cmd_oper = "UPDATE [Model Elements] SET [Record Status] = ? WHERE [Index] = ?";
using( OleDbCommand cmd = new OleDbCommand( cmd_oper, svr_conn ) )
{
    cmd.Parameters.AddWithValue( "anything-name-doesnt-matter", "Disabled" );
    cmd.Parameters.Add( "its-position-that-matters", OleDbType.Integer ).Value = 2;
    cmd.ExecuteNonQuery();
}

为了它的价值,你应该合理地命名你的参数(我在上面将它们命名为愚蠢的以证明名称无关紧要)因为这个想法是一旦准备好,你可以多次执行语句只需更改参数:

    cmd.Parameters["its-position-that-matters"].Value = 3;
    cmd.ExecuteNonQuery();
    cmd.Parameters["its-position-that-matters"].Value = 4;
    cmd.ExecuteNonQuery();
    cmd.Parameters["its-position-that-matters"].Value = 5;
    cmd.ExecuteNonQuery();
    cmd.Parameters["its-position-that-matters"].Value = 6;
    cmd.ExecuteNonQuery();

这里我也 运行 更新了 index 值 3、4、5 和 6,只需更改参数值并重新 运行ning。因此,我最好为 "index" 参数选择一个合理的名称,以使代码更具可读性

史蒂夫在他的评论中指出,他相信您 可以 将命名参数放入查询中,但名称会被忽略(它们基本上被视为 ? 标记)所以你仍然需要按照占位符出现的相同顺序添加参数值。如果您在查询中重复占位符,则必须将其重复添加到参数集合中。我不评论史蒂夫断言的准确性;我一直使用 ?

最终,这都是很好的证据,表明您真的应该开始学习使用像 Entity Framework 这样的数据访问库,并停止在您的按钮点击中编写 SQL 字符串事件处理程序 - 这不是一个好的编码方式。如果您从一开始就使用 EF,您甚至都不会遇到这个问题。不过,使用参数化查询对您有好处。现在去看看 EF,把这个 90 年代笨拙的数据访问方式抛在脑后:)