插入 MS Access 语句中的语法错误

Syntax error in INSERT statement into MS Access

我在下面的 INSERT 语句中找不到语法错误。

public partial class doRegister : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string str = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\database";
        using (OleDbConnection con = new OleDbConnection(str))
        using (OleDbCommand cmd = con.CreateCommand())
        {
            cmd.CommandText = "INSERT INTO users (staffID,accessLevelIdD,username,password,email) VALUES (@staffID, '2', @username,@password,@email)";
            cmd.Parameters.AddWithValue("@staffID", Request.Form["staffid"]);
            cmd.Parameters.AddWithValue("@password",Request.Form["confpassword"]);
            cmd.Parameters.AddWithValue("@username", Request.Form["username"]);
            cmd.Parameters.AddWithValue("@email", Request.Form["email"]);
            con.Open();
            try
            {
                cmd.ExecuteNonQuery();
                MessageBox.Show("Successfully registered!");
                Response.Redirect("Login.aspx");
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
            }
            finally
            {
                con.Close();
            }
        }
    }
}

似乎 Password 是 OLE DB 提供程序中的 reserved keyword。将它与方括号一起使用,例如 [Password]。但作为最佳实践,请将其更改为 非保留 字。

并且OleDbCommand不支持命名参数。

来自 documentation;

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.

在文档中说 ?必须使用实际上,它不是。命名参数 do 有效,但名称无关; CommandText 中参数的位置和它们的添加顺序仍然很重要。

并且不要再使用 AddWithValue。它有时 可能 产生意想不到的结果。使用 .Add() method 或它的重载。

阅读:Can we stop using AddWithValue() already?

最后,您不需要在 finally 块中手动关闭与 con.Close() 的连接,因为 using 语句会自动处理它。

顺便说一下,我不得不说,accessLevelIdD 列以 ID 结尾,因此从名称上看它像是一种数字类型。如果是(或者应该或不应该),您需要将值作为 2 而不是 '2'.