Получение ошибок с параметризованным обновлением Sub

Не знаю, почему это не работает.

У меня есть простая форма с некоторыми текстовыми полями и выпадающими списками. Отображает профиль сотрудника. Пользователи должны иметь возможность вручную редактировать поля и нажимать «Сохранить». Когда они нажимают сохранить, я продолжаю получать ошибки.

Вопрос 1. Как обработать вставку значений Null для типов данных SmallDateTime?

Q2: Что я делаю неправильно с TinyInt (SqlServer 2005) в JobGrade?

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>

I open the form and fill it out correctly. I'll enter something like "4" (no quotes) for JobGrade. It still says "conversion from strink ''" like its not even seeing when I input items on the form.

Ошибки ниже:

System.InvalidCastException: преобразование строки "" в тип "Byte" недопустимо. ---> System.FormatException: Входная строка имеет неверный формат. в Microsoft.VisualBasic.CompilerServices.Conversions.ParseDouble(String Value, NumberFormatInfo NumberFormat) в Microsoft.VisualBasic.CompilerServices.Conversions.ToByte(String Value) --- Конец внутренней трассировки стека исключений --- в Microsoft.VisualBasic.CompilerServices. Conversions.ToByte (строковое значение) в Profile.btnSave_Click (отправитель объекта, EventArgs e) в

Обновить

Проблема DBNull.Value решена. JobGrade и Role все еще остаются проблемами. При создании некоторых точек останова он не извлекает содержимое текстового поля или раскрывающегося списка.

** Updated Code **

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

    Session("sProfileEUID") = Nothing
    Response.Redirect("~/Management/EditUsers.aspx")

End Sub

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 = 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()

    Catch ex As Exception

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

    Finally

        sqlJobsDB.Close()

    End Try

End Sub

Редактировать 2:

Поэтому я в значительной степени отказался от этого и вместо этого переместил таблицу в FormView ItemTemplate, а также в EditTemplate. Я изменил его, как описано в следующей ссылке. http://www.beansoftware.com/ASP.NET-Tutorials/FormView-Control.aspx


person Lucretius    schedule 25.08.2011    source источник
comment
Пожалуйста, подтвердите, что вы не сбрасываете значения текстовых полей на нуль в реализации события Page_Load, потому что если вы введете 4 в Textbox1, то CINT(Textbox1.Text) будет работать.   -  person NoAlias    schedule 30.08.2011
comment
@NoAlias ​​Это может быть так, однако я могу успешно обновить две даты в форме для @CADate и @JobDate, однако после ввода даты я не могу удалить ее с помощью DBNull.Value. Я открываю SQL Server 2005 и могу написать оператор обновления, и он отлично работает... понятия не имею, почему это так сложно.   -  person Lucretius    schedule 31.08.2011


Ответы (2)


Q1: Убедитесь, что структура таблицы допускает пустые значения, и задайте для параметра значение DBNull.Value.

Q2:

If IsNumeric(txtJobGrade.Text) Then

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

Else

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

End If

Вы всегда можете сделать это раскрывающимся списком, чтобы предотвратить ввод данных с открытым концом.

person NoAlias    schedule 25.08.2011
comment
Вопрос 1. Если я использую что-то вроде If txtCADate.Text = "" Then sqlCmdUpdate.Parameters("@CADate").Value.IsDBNull(), возникает исключение ссылки Null, даже если таблица в базе данных настроена на прием нулей. Использование sqlCmdUpdate.Parameters("@CADate").Value = DBNull не работает. - person Lucretius; 26.08.2011
comment
IsDBNull() — это метод, который сообщает вам, является ли значение параметра нулевым. Попробуйте .Value = DBNull.Value и посмотрите, поможет ли это. - person NoAlias; 26.08.2011
comment
О, я вижу, я неправильно прочитал ваш первоначальный комментарий. - Новая проблема в форме, если я удалю все из текстового поля, он должен передать DBNull.Value в базу данных во время оператора обновления, но он терпит неудачу и обновляет экран, не выдавая мне сообщения об ошибке. - person Lucretius; 26.08.2011
comment
Вы явно устанавливаете его в DBNull.Value, когда текстовое поле пусто, или просто предполагаете? Кроме того, вы можете пройти через него с точками останова, чтобы получить сообщение об ошибке. - person NoAlias; 26.08.2011
comment
Везде в моем исходном посте, где разветвления If/Then, и я присваиваю значение 0 чему-то, находится там, где сейчас находится DBNull.Value. Я прохожу это с точками останова сейчас, спасибо. - person Lucretius; 26.08.2011
comment
Без проблем. Отредактируйте вопрос или опубликуйте больше комментариев, если у вас возникнет больше проблем. Я зайду чуть позже. - person NoAlias; 26.08.2011
comment
Я обновил основной пост, проблема, с которой я столкнулся сейчас, заключается в том, что при использовании метода DBNull.Value я не могу вставить нулевое значение в базу данных. Решение Cint() по-прежнему не работает, оно говорит мне, что вы не можете преобразовать строку в Int32, когда я ввожу что-то вроде 4. - person Lucretius; 27.08.2011

Немного странно видеть, как вы сделали параметры. Как правило, я ожидаю увидеть что-то большее в этом духе:

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...

Попробуйте внести некоторые из этих изменений и посмотрите, какие (если есть) ошибки вы все еще получаете.

person Chains    schedule 31.08.2011
comment
Я ценю все указатели. Пройдет несколько дней, прежде чем у меня будет время снова покопаться в этом, но я дам вам знать, как все идет. - person Lucretius; 03.09.2011