【问题标题】:Why is my database field 'not updateable'?为什么我的数据库字段“不可更新”?
【发布时间】:2019-05-29 19:29:34
【问题描述】:

我正在开发一个程序,允许用户参加测试并获得分数、百分比和等级。这些将存储在名为“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()

【问题讨论】:

  • 尝试位置参数是否有帮助:只需在查询中使用? 作为参数并以正确的顺序添加值
  • OleDB 参数必须按照它们在 sql 语句中出现的正确顺序。所以@Score 应该是第一位的,等等。你应该发布你的代码。
  • 访问中的参数是基于位置的,没有命名,尽管您可以根据自己的理智来命名它们。参数出现在查询中的顺序与参数必须出现在参数集合中的顺序完全相同。您也不能在多个位置重复使用相同的参数,因为它是位置性的。通常使用 ? 作为占位符而不是 @name 但同样,只要顺序正确,这并不重要。
  • 我仍然遇到同样的错误。我在 VB.NET 本身中添加参数的顺序是否有任何影响,即“Parameters.AddWithValue...”?
  • 那么您很幸运,或者您的查询正在更新错误的字段。在幕后,您的命名参数@example 正在变成一个“?”。所以顺序很重要,100%。

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


【解决方案1】:

将您的数据对象保存在本地,以便确保它们已关闭和处置。即使出现错误,Using...End Using 块也会为您执行此操作。

不要使用 .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 语句中出现的顺序必须与它们添加到参数集合中的顺序相匹配。

.ExecuteReader 用于检索记录。您要执行更新语句,因此请使用 .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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 2016-12-12
    • 1970-01-01
    • 2020-10-27
    • 2012-05-31
    • 2019-12-02
    相关资源
    最近更新 更多