从datagridview向sql数据库插入数据时,从“DBNull”类型到“String”类型的转换无效

时间:2014-02-10 02:18:14

标签: sql vb.net datagridview

大家好,我是vb.net的新手程序员,所以到目前为止我有这个问题,我正在寻找相关的答案,但没有找到运气,所以我决定发布我的问题。

所以这就是。

Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click

    Dim connstr As String = "server=midtelephone\sqlexpress; database=testdb; user= sa; password=sa;"

    cmdconn = New SqlConnection
    cmd = New SqlCommand
    cmdconn.ConnectionString = sqlstr
    cmd.Connection = cmdconn
    cmdconn.Open()

    Dim period, VOUCH_AMT, INDIVIDUAL_AMT, check_no, D_MAILED, DIR_NO As String
    For i As Integer = 0 To Me.DataGridView1.Rows.Count - 1

        'cmd.CommandText = "insert into tobee.EBD_BILLHISTORY(period, vouch_amt, individual_amt, check_no, d_mailed, dir_no) values" &_
        '" (@period,@VOUCH_AMT,@INDIVIDUAL_AMT,@check_no,@D_MAILED,@DIR_NO)"

        period = Me.DataGridView1.Rows(i).Cells(0).Value()
        VOUCH_AMT = Me.DataGridView1.Rows(i).Cells(1).Value()
        INDIVIDUAL_AMT = Me.DataGridView1.Rows(i).Cells(2).Value()
        check_no = Me.DataGridView1.Rows(i).Cells(3).Value()
        D_MAILED = Me.DataGridView1.Rows(i).Cells(4).Value()
        DIR_NO = Me.DataGridView1.Rows(i).Cells(5).Value()

        cmd.CommandText = "insert into tobee.EBD_BILLHISTORY(period, vouch_amt, individual_amt, check_no, d_mailed, dir_no)values" & _
            "('" & period & "','" & VOUCH_AMT & "','" & INDIVIDUAL_AMT & "','" & check_no & "','" & D_MAILED & "', '" & DIR_NO & "')"
        cmd.ExecuteNonQuery()
        MsgBox("Saved")
    Next
    cmdconn.Close()

End Sub

我想通过datagridview更新我的sql数据库。

(从另一个sql查询调用datagridview - cmd.CommandText =“选择句点,VOUCH_AMT,INDIVIDUAL_AMT,check_no,D_MAILED,DIR_NO来自tobee.EBD_BILLHISTORY,其中CLAIM_NO喜欢'”+ claimno.ToString +“'”选择句点,来自tobee.EBD_BILLHISTORY的VOUCH_AMT,INDIVIDUAL_AMT,check_no,D_MAILED,DIR_NO,其中CLAIM_NO喜欢'“+ claimno.ToString +”'“”

现在的问题是, 单击保存按钮时出现错误。 每当我点击保存按钮,其他列都空了。出现错误 “invalidcastexception未处理”(在某些空行上) - 从'DBNull'类型到'String'类型的转换无效。

aaaaaand ..在每行中插入不同的值时会出现另一个错误。 特别是当我想插入日期时间值时。不太熟悉代码。

我的代码有问题吗? 除了单击保存按钮,所有进程都很好(如提取数据)。 或更新我的数据库。提前致谢。你的回复非常感谢。

2 个答案:

答案 0 :(得分:1)

尝试下面的代码,我还更新了代码以避免SQL注入。 您必须检查来自单元格的值是否为DBNull并正确处理

Dim connstr As String = "server=midtelephone\sqlexpress; database=testdb; user= sa; password=sa;"

cmdconn = New SqlConnection
cmd = New SqlCommand
cmdconn.ConnectionString = connstr 'sqlstr
cmd.Connection = cmdconn
cmdconn.Open()

Dim period, VOUCH_AMT, INDIVIDUAL_AMT, check_no, D_MAILED, DIR_NO As String
For i As Integer = 0 To Me.DataGridView1.Rows.Count - 1

    'cmd.CommandText = "insert into tobee.EBD_BILLHISTORY(period, vouch_amt, individual_amt, check_no, d_mailed, dir_no) values" &_
    '" (@period,@VOUCH_AMT,@INDIVIDUAL_AMT,@check_no,@D_MAILED,@DIR_NO)"

    With Me.DataGridView1.Rows(i)

        If IsDBNull(.Cells(0).Value()) OrElse .Cells(0).Value() Is Nothing OrElse .Cells(0).Value().ToString().Trim() = "" Then
            period = ""
        Else
            period = .Cells(0).Value()
        End If
        If IsDBNull(.Cells(1).Value()) OrElse .Cells(1).Value() Is Nothing OrElse .Cells(1).Value().ToString().Trim() = "" Then
            VOUCH_AMT = "0"
        Else
            VOUCH_AMT = .Cells(1).Value()
        End If
        If IsDBNull(.Cells(2).Value()) OrElse .Cells(2).Value() Is Nothing OrElse .Cells(2).Value().ToString().Trim() = "" Then
            INDIVIDUAL_AMT = "0"
        Else
            INDIVIDUAL_AMT = .Cells(2).Value()
        End If
        If IsDBNull(.Cells(3).Value()) OrElse .Cells(3).Value() Is Nothing OrElse .Cells(3).Value().ToString().Trim() = "" Then
            check_no = ""
        Else
            check_no = .Cells(3).Value()
        End If
        If IsDBNull(.Cells(4).Value()) OrElse .Cells(4).Value() Is Nothing OrElse .Cells(4).Value().ToString().Trim() = "" Then
            D_MAILED = ""
        Else
            D_MAILED = .Cells(4).Value()
        End If
        If IsDBNull(.Cells(5).Value()) OrElse .Cells(5).Value() Is Nothing OrElse .Cells(5).Value().ToString().Trim() = "" Then
            DIR_NO = ""
        Else
            DIR_NO = .Cells(5).Value()
        End If

        'period = IIf(IsDBNull(.Cells(0).Value()), "", .Cells(0).Value())
        'VOUCH_AMT = IIf(IsDBNull(.Cells(1).Value()), "0", IIf(.Cells(1).Value().ToString().Trim() = "", "0", .Cells(1).Value()))
        'INDIVIDUAL_AMT = IIf(IsDBNull(.Cells(2).Value()), "0", IIf(.Cells(2).Value().ToString().Trim() = "", "0", .Cells(2).Value()))
        'check_no = IIf(IsDBNull(.Cells(3).Value()), "", .Cells(3).Value())
        'D_MAILED = IIf(IsDBNull(.Cells(4).Value()), "", .Cells(4).Value())
        'DIR_NO = IIf(IsDBNull(.Cells(5).Value()), "", .Cells(5).Value())

    End With

    cmd.CommandText = "insert into tobee.EBD_BILLHISTORY(period, vouch_amt, individual_amt, check_no, d_mailed, dir_no)values" & _
        "('" & period.Replace("'", "''") & "'," & VOUCH_AMT & "," & INDIVIDUAL_AMT & ",'" & check_no.Replace("'", "''") & "','" & D_MAILED.Replace("'", "''") & "', '" & DIR_NO.Replace("'", "''") & "')"
    cmd.ExecuteNonQuery()
    MsgBox("Saved")
Next
cmdconn.Close()

答案 1 :(得分:0)

最好将值作为参数传递给command。检查下面的一小部分代码:

cmd.CommandText = "insert into tobee.EBD_BILLHISTORY(period, vouch_amt, individual_amt, check_no, d_mailed, dir_no) values" &_
    " (@period,@VOUCH_AMT,@INDIVIDUAL_AMT,@check_no,@D_MAILED,@DIR_NO)"
cmd.parameters.addwithvalue("@Period", iif(period is dbnull.value, 0, period))