尝试从 Access 数据库中删除时出现 C# OleDb 异常“没有为一个或多个必需参数提供值”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18112264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:19:29  来源:igfitidea点击:

C# OleDb Exception "No value given for one or more required parameters" while trying to delete from Access database

c#ms-accessoledbconnectionoledbexception

提问by user2594788

I have a table with "SEMESTER, SUBJECT, OFFER, RESULT" where "SEMESTER" & "SUBJECT" is PRIMARY KEY. When i use the query

我有一个带有“学期、主题、报价、结果”的表格,其中“学期”和“主题”是主键。当我使用查询时

"DELETE FROM Course_Information WHERE Semester = 1 AND Subject = 'CSE-414' ;

"DELETE FROM Course_Information WHERE Semester = 1 AND Subject = 'CSE-414' ;

Its working perfectly in access database but i always get exception when i tried to use it in my c# code.

它在访问数据库中完美运行,但是当我尝试在我的 c# 代码中使用它时,我总是遇到异常。

Moreover its works if i use "DELETE FROM Course_Information WHERE Semester = 1 ;

此外,如果我使用“DELETE FROM Course_Information WHERE Semester = 1 ;

I want to use both "SUBJECT" & "SEMESTER" In the WHERE condition (Because there could be different subject in the same semester)

我想在 WHERE 条件中同时使用“SUBJECT”和“SEMESTER”(因为同一学期可能有不同的主题)

See my code,

看我的代码

connection_string = aConnection.return_connectionString(connection_string);
            string sql_query = "DELETE FROM Course_Information WHERE Semester = " + this.textBox1.Text + " AND Subject = " + this.textBox2.Text + " ;";

            OleDbConnection connect = new OleDbConnection(connection_string);
            OleDbCommand command = new OleDbCommand(sql_query, connect);
            try
            {
                connect.Open();
                OleDbDataReader reader = command.ExecuteReader();
                MessageBox.Show("Delete Successful!");
                connect.Close();
                UpdateDatabase();
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

采纳答案by HansUp

Include the quotes around the value you get from this.textBox2.Textas in your working sample query.

this.textBox2.Text在您的工作示例查询中包含您从中获得的值周围的引号。

" AND Subject = '" + this.textBox2.Text + "';";

Imagine this.textBox2.Textcontains the text foo. Without adding those quotes in the WHEREclause the db engine would see ... WHERE Semester = 1 AND Subject = fooBut it can't find anything in the data source named foo, so assumes it must be a parameter. You need the quotes to signal the db engine it's a string literal value, 'foo'.

想象this.textBox2.Text包含文本foo。如果不在WHERE子句中添加这些引号,数据库引擎会看到... WHERE Semester = 1 AND Subject = foo但它在名为 的数据源中找不到任何内容foo,因此假定它必须是一个参数。您需要引号来通知数据库引擎它是一个字符串文字值'foo'

Actually if you switch to a parameter query, you can avoid this type of problem because you won't need to bother with those quotes in the DELETEstatement. And a parameter query will also safeguard you against SQL injection. If a malicious user can enter ' OR 'a' = 'ain this.textBox2.Text, all rows in the table would be deleted.

实际上,如果您切换到参数查询,则可以避免这种类型的问题,因为您不需要打扰DELETE语句中的那些引号。并且参数查询还可以保护您免受 SQL 注入。如果恶意用户可以输入' OR 'a' = 'ain this.textBox2.Text,则表中的所有行都将被删除。

回答by AliMusa

If you got a same error for "insert" query you can use this method for avoid exception

如果“插入”查询出现相同的错误,您可以使用此方法来避免异常

string sqlQuery = "INSERT into EndResultOfTestCases(IDsOfCases,TestCaseName,ResultCase,ResultLog) VALUES(@ids, @casename, @results, @logs)";

        connection = new OleDbConnection(connectionStringToDB);
        command = new OleDbCommand(sqlQuery, connection);
        command.Parameters.AddWithValue("@ids",IDs);
        command.Parameters.AddWithValue("@casename", CaseName);
        command.Parameters.AddWithValue("@results", resultOfCase);
        command.Parameters.AddWithValue("@logs", logs);
        connection.Open();
        command.ExecuteNonQuery();
        connection.Close();
    }