【问题标题】:Getting errors with Parameterized Update Sub使用参数化更新子获取错误
【发布时间】:2011-08-25 21:04:42
【问题描述】:

不知道为什么这不起作用。

我有一个带有一些文本框和下拉列表的简单表单。它显示员工的个人资料。用户应该能够手动编辑字段并单击保存。当他们点击保存时,我不断收到错误消息。

Q1:如何处理为 SmallDateTime 数据类型插入 Null 值?

Q2:JobGrade 上的 TinyInt (SqlServer 2005) 有什么问题?

Option Explicit On 
Imports System 
Imports System.Data 
Imports System.Data.SqlClient 

Protected Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSave.Click

    Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
    Dim sqlCmdUpdate As SqlCommand = sqlJobsDB.CreateCommand()

    Try

        sqlJobsDB.Open()
        sqlCmdUpdate.CommandText = _
            "UPDATE tblEmployee " + _
             "SET Firstname = @Firstname, LastName = @LastName, HiredLastName = @HiredLastName, " + _
                "DateHired = @DateHired, Role = @Role, CADate = @CADate, CAType = @CAType, " + _
                "JobDate = @JobDate, JobGrade = @JobGrade " + _
             "WHERE EUID = '" & Session("sProfileEUID") & "';"

        sqlCmdUpdate.Parameters.Add("@FirstName", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@LastName", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@HiredLastName", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@DateHired", SqlDbType.SmallDateTime)
        sqlCmdUpdate.Parameters.Add("@Role", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@CADate", SqlDbType.SmallDateTime)
        sqlCmdUpdate.Parameters.Add("@CAType", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@JobDate", SqlDbType.SmallDateTime)
        sqlCmdUpdate.Parameters.Add("@JobGrade", SqlDbType.TinyInt)

        sqlCmdUpdate.Parameters("@FirstName").Value = txtFirstName.Text
        sqlCmdUpdate.Parameters("@LastName").Value = txtLastName.Text
        sqlCmdUpdate.Parameters("@HiredLastName").Value = txtHiredLastName.Text
        sqlCmdUpdate.Parameters("@DateHired").Value = txtDateHired.Text
        sqlCmdUpdate.Parameters("@Role").Value = ddlRole.SelectedValue.ToString

        If txtCADate.Text = "" Then
            sqlCmdUpdate.Parameters("@CADate").Value = 0
        Else
            sqlCmdUpdate.Parameters("@CADate").Value = txtCADate.Text
        End If

        sqlCmdUpdate.Parameters("@CAType").Value = ddlCAType.SelectedValue

        If txtJobDate.Text = "" Then
            sqlCmdUpdate.Parameters("@JobDate").Value = 0
        Else
            sqlCmdUpdate.Parameters("@JobDate").Value = txtJobDate.Text
        End If

        sqlCmdUpdate.Parameters("@JobGrade").Value = CByte(txtJobGrade.Text)

        sqlCmdUpdate.ExecuteNonQuery()

    Catch ex As Exception

        'Debugging
        lblErrMsg.Text = ex.ToString
        lblErrMsg.Visible = True

    Finally

        sqlJobsDB.Close()

    End Try

End Sub</code>

我打开表格并正确填写。 我将为 JobGrade 输入类似“4”(不带引号)的内容。它仍然说“从 strink 转换”,就像我在表单上输入项目时甚至看不到一样。

错误如下:

System.InvalidCastException:从字符串“”到类型“字节”的转换无效。 ---> System.FormatException:输入字符串的格式不正确。在 Microsoft.VisualBasic.CompilerServices.Conversions.ParseDouble(String Value, NumberFormatInfo NumberFormat) 在 Microsoft.VisualBasic.CompilerServices.Conversions.ToByte(String Value) --- 内部异常堆栈跟踪结束 --- 在 Microsoft.VisualBasic.CompilerServices。 Conversions.ToByte(String Value) at Profile.btnSave_Click(Object sender, EventArgs e) in

更新

DBNull.Value 问题已解决。 JobGrade 和 Role 仍然是问题。在它上面抛出一些断点时不会获取文本框或下拉列表的内容。

** 更新代码 **

Protected Sub btnCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) 处理 btnCancel.Click

    会话(“sProfileEUID”)= 无
    Response.Redirect("~/Management/EditUsers.aspx")

结束子

Protected Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) 处理 btnSave.Click

    将 sqlJobsDB 调暗为新的 SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
    将 sqlCmdUpdate 调暗为 SqlCommand = sqlJobsDB.CreateCommand()

    尝试

        sqlJobsDB.Open()
        sqlCmdUpdate.CommandText = _
            “更新 tblEmployee” + _
             "SET FirstName = @FirstName,LastName = @LastName,HiredLastName = @HiredLastName," + _
                "DateHired = @DateHired,角色 = @Role,CADate = @CADate,CAType = @CAType," + _
                “JobDate = @JobDate,JobGrade = @JobGrade” + _
             "WHERE EU​​ID = '" & Session("sProfileEUID") & "';"

        sqlCmdUpdate.Parameters.Add("@FirstName", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@LastName", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@HiredLastName", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@DateHired", SqlDbType.SmallDateTime)
        sqlCmdUpdate.Parameters.Add("@Role", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@CADate", SqlDbType.SmallDateTime)
        sqlCmdUpdate.Parameters.Add("@CAType", SqlDbType.VarChar)
        sqlCmdUpdate.Parameters.Add("@JobDate", SqlDbType.SmallDateTime)
        sqlCmdUpdate.Parameters.Add("@JobGrade", SqlDbType.TinyInt)

        sqlCmdUpdate.Parameters("@FirstName").Value = txtFirstName.Text
        sqlCmdUpdate.Parameters("@LastName").Value = txtLastName.Text
        sqlCmdUpdate.Parameters("@HiredLastName").Value = txtHiredLastName.Text
        sqlCmdUpdate.Parameters("@DateHired").Value = txtDateHired.Text
        sqlCmdUpdate.Parameters("@Role").Value = ddlRole.SelectedValue.ToString

        If txtCADate.Text  "" Then sqlCmdUpdate.Parameters("@CADate").Value = CDate(txtCADate.Text)
        If txtCADate.Text = "" Then sqlCmdUpdate.Parameters("@CADate").Value = DBNull.Value

        If ddlCAType.Text  "" Then sqlCmdUpdate.Parameters("@CAType").Value = ddlCAType.SelectedValue
        If ddlCAType.Text = "" Then sqlCmdUpdate.Parameters("@CAType").Value = DBNull.Value

        If txtJobDate.Text  "" Then sqlCmdUpdate.Parameters("@JobDate").Value = CDate(txtJobDate.Text)
        If txtJobDate.Text = "" Then sqlCmdUpdate.Parameters("@JobDate").Value = DBNull.Value

        If txtJobGrade.Text  "" Then sqlCmdUpdate.Parameters("@JobGrade").Value = CInt(txtJobGrade.Text)
        If txtJobGrade.Text = "" Then sqlCmdUpdate.Parameters("@JobGrade").Value = DBNull.Value

        sqlCmdUpdate.ExecuteNonQuery()

    抓住前任作为例外

        lblErrMsg.Text = ex.ToString
        lblErrMsg.Visible = True

    最后

        sqlJobsDB.Close()

    结束尝试

结束子

编辑 2:

所以我几乎放弃了这一点,而是将表格移到了 FormView ItemTemplate 中,也带有 EditTemplate。我按照以下链接中的说明对其进行了修改。 http://www.beansoftware.com/ASP.NET-Tutorials/FormView-Control.aspx

【问题讨论】:

  • 请确认您没有在 Page_Load 事件实现中将文本框的值重置为空,因为如果您在 Textbox1 中输入 4,那么 CINT(Textbox1.Text) 将起作用。
  • @NoAlias 可能是这种情况,但是我可以成功更新“@CADate”和“@JobDate”表单上的两个日期,但是在输入日期后我无法使用删除它DBNull.值。我打开 SQL Server 2005,我可以编写更新语句,它工作正常……不知道为什么这么难。

标签: tsql asp.net-4.0 vb.net-2010


【解决方案1】:

Q1:确保表结构允许空值并将参数值设置为 DBNull.Value。

第二季度:

If IsNumeric(txtJobGrade.Text) Then

sqlCmdUpdate.Parameters("@JobGrade").Value = CInt(txtJobGrade.Text) 

Else

sqlCmdUpdate.Parameters("@JobGrade").Value = 0 'Or Default Value

End If

您始终可以将其设为下拉列表以防止开放式数据输入。

【讨论】:

  • Q1:如果我使用If txtCADate.Text = "" Then sqlCmdUpdate.Parameters("@CADate").Value.IsDBNull() 之类的东西,即使数据库中的表配置为接受空值,它也会引发空引用异常。使用sqlCmdUpdate.Parameters("@CADate").Value = DBNull 不起作用。
  • IsDBNull() 是一种告诉您参数的值是否为空的方法。试试 .Value = DBNull.Value 看看是否有帮助。
  • 哦,我明白了,我读错了您最初的评论。 - 新问题,在表单上,​​如果我删除文本框中的所有内容,它应该在 Update 语句期间将 DBNull.Value 输入数据库,但它失败并刷新屏幕,没有错误消息。
  • 当文本框为空或只是假设时,您是否将其显式设置为 DBNull.Value?此外,您可以使用断点单步执行以获取错误消息。
  • 在我原来的帖子中 If/Then 分叉的地方,我将“0”的值分配给现在“DBNull.Value”所在的位置。我现在用断点遍历它,谢谢。
【解决方案2】:

看到你是如何完成参数的有点奇怪。通常,我希望看到更多类似这些方面的内容:

With sqlCmdUpdate.Parameters
   .clear()
   .addWithValue("@parm1", mytextbox1.text)
   .addWithValue("@parm2", mytextbox2.text)
End With

一方面,.add 已被弃用 - 仍然有效,但需要注意一些问题 (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparametercollection.addwithvalue .aspx)。

其次,最好致电.clear()

另外——您可能会考虑一种更标准的检查值的方法——例如:

If txtJobGrade.Text <> "" Then...

最好写成

If NOT string.isnullorempty(me.txtJobGrade.text) Then...

尝试进行一些更改,看看您仍然遇到什么(如果有)错误。

【讨论】:

  • 感谢所有的指点。几天后我才有时间真正深入研究这个问题,但我会让你知道它是怎么回事。
猜你喜欢
  • 1970-01-01
  • 2023-02-05
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多