带参数的更新命令给出 "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 年代笨拙的数据访问方式抛在脑后:)
我有以下代码:
/*
// 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 年代笨拙的数据访问方式抛在脑后:)