问题是 OleDb(和 Odbc 也是)不支持命名参数。
它只支持所谓的位置参数。
换句话说:您在将参数添加到命令参数列表时为其提供的名称无关紧要。它仅由 OleDbCommand 类在内部使用,因此它可以区分和引用参数。
重要的是您将参数添加到列表中的顺序。它必须与 SQL 语句中通过问号字符 ( ?
) 引用的参数的顺序相同。
但这里有一个解决方案,允许您在 SQL 语句中使用命名参数。它基本上用问号替换 SQL 语句中的所有参数引用,并相应地重新排序参数列表。OdbcCommand 类的工作方式相同,您只需在代码中将“OleDb”替换为“Odbc”即可。
使用如下代码:
command.CommandText = "SELECT * FROM Contact WHERE FirstName = @FirstName";
command.Parameters.AddWithValue("@FirstName", "Mike");
command.ConvertNamedParametersToPositionalParameters();
这是代码
public static class OleDbCommandExtensions
{
public static void ConvertNamedParametersToPositionalParameters(this OleDbCommand command)
{
//1. Find all occurrences of parameter references in the SQL statement (such as @MyParameter).
//2. Find the corresponding parameter in the commands parameters list.
//3. Add the found parameter to the newParameters list and replace the parameter reference in the SQL with a question mark (?).
//4. Replace the commands parameters list with the newParameters list.
var newParameters = new List<OleDbParameter>();
command.CommandText = Regex.Replace(command.CommandText, "(@\\w*)", match =>
{
var parameter = command.Parameters.OfType<OleDbParameter>().FirstOrDefault(a => a.ParameterName == match.Groups[1].Value);
if (parameter != null)
{
var parameterIndex = newParameters.Count;
var newParameter = command.CreateParameter();
newParameter.OleDbType = parameter.OleDbType;
newParameter.ParameterName = "@parameter" + parameterIndex.ToString();
newParameter.Value = parameter.Value;
newParameters.Add(newParameter);
}
return "?";
});
command.Parameters.Clear();
command.Parameters.AddRange(newParameters.ToArray());
}
}