为什么我的数据库字段“不可更新”?

时间:2019-05-29 19:29:34

标签: sql vb.net ms-access visual-studio-2013

我正在开发一个程序,该程序允许用户参加测试并为此获得分数,百分比和等级。这些将存储在名为“ tblStudentScores”的数据表中。下面的SQL代码旨在在用户完成测试后更新相关记录,以便存储该测试的最新分数。

UPDATE tblStudentScores
SET Score = @Score, Percentage = @Perc, Grade = @Grade, CompletedTask = True
WHERE SpecificTaskID = @SpecID AND StudentID = @StudID;

在MS Access中测试此SQL时,它可以完美运行。但是,当我尝试使用与VB.NET中的OleDBCommand相同的查询时,没有任何反应。没有错误消息,但是代码也不会更新表。

我认为这可能是由于参数所致,所以我在查询顶部明确声明了这些参数:

PARAMETERS @SpecID Number, @StudID Number, @Score Number, @Perc Number, @Grade Text;

现在,我收到以下错误消息,而不是什么都没有发生:

An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll
Additional information: Cannot update 'Score'; field not updateable.

正如我之前所说,该查询在MS Access的查询设计器中成功完成,因此该字段必须是可更新的。这里可能出什么问题了?

编辑:经过进一步测试,我发现当使用固定输入而不是参数时,该查询确实在VB中工作。因此,问题显然出在参数上,但是可能是什么问题?

编辑:我在其中创建和使用查询的整个代码如下:

 Dim cmd As New OleDbCommand("PARAMETERS @Score Number, @Perc Number, @Grade Text, @SpecID Number, @StudID Number; UPDATE tblStudentScores " & _
                                    "SET Score = @Score, Percentage = @Perc, Grade = @Grade, CompletedTask = True " & _
                                    "WHERE SpecificTaskID = @SpecID AND StudentID = @StudID;", connection)


        With cmd.Parameters
            .AddWithValue("@Score", score)
            .AddWithValue("@Perc", percentage)
            .AddWithValue("@Grade", grade)
            .AddWithValue("@SpecID", specificIDorder(cbxCurrentTasks.SelectedIndex))
            .AddWithValue("@StudID", id)
        End With

        connection.Open()
        cmd.ExecuteReader()
        connection.Close()

1 个答案:

答案 0 :(得分:1)

将数据对象保留在本地,以便确保它们已关闭并处置。即使出现错误,“使用...结束使用”块也会为您执行此操作。

请勿使用.AddWithValue。请参阅http://www.dbdelta.com/addwithvalue-is-evil/https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/#comment-8442以了解原因。您将必须在数据库中检查字段的数据类型。我只是猜到了。

在Access中,参数名称无关紧要。它们在sql语句中出现的顺序必须与它们添加到Parameters集合的顺序匹配。

.ExecuteReader用于检索记录。您要执行Update语句,因此请使用.ExecuteNonQuery。

我不确定您对specificIDorder(cbxCurrentTasks.SelectedIndex的处理方式 specificIDorder是基于组合框中选择的索引返回一些值的函数吗?如果不是,则需要重新考虑该参数的值。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Using cn As New OleDbConnection("Your connection string")
        Using cmd As New OleDbCommand("Update tblStudentScores 
                                Set Score = @Score, 
                                Percentage = @Perc,
                                Grade = @Grade, 
                                CompletedTask = True 
                                WHERE 
                                SpecificTaskID = @SpecID 
                                And 
                                StudentID = @StudID;", cn)
            With cmd.Parameters
                .Add("@Score", OleDbType.Integer).Value = score
                .Add("@Perc", OleDbType.Integer).Value = percentage
                .Add("@Grade", OleDbType.VarChar).Value = grade
                .Add("@SpecID", OleDbType.Integer).Value = CInt(specificIDorder(cbxCurrentTasks.SelectedIndex))
                .Add("@StudID", OleDbType.Integer).Value = id
            End With
            cn.Open()
            cmd.ExecuteNonQuery()
        End Using
    End Using
End Sub