0

这是我在 vb.net 中的代码,当我将插入查询从 VB.net 传递到 SQL 服务器时,我在查询时遇到异常,即对象引用未设置为实例对象,在 sql 字段中允许为 null 并且 ID 是自动增量. 我的一位同伴说使用记录集并告诉类似的条件,但我完全不知道在 VB.net 中的 New 中的记录集,请帮助我,我该怎么办,

折叠 | 复制代码

Imports System.Data
Imports System.Data.SqlClient
Public Class MaintenanceTask
    Dim cn As New System.Data.SqlClient.SqlConnection
    Sub connect()
        cn = New System.Data.SqlClient.SqlConnection("Data Source=localhost;Initial Catalog=Fleet Maintainance;Integrated Security=True")
    End Sub
    Sub lockall()
        cBx1.Enabled = False
        cBx2.Enabled = False
        tBx1.Enabled = False
        tBx2.Enabled = False
        tBx3.Enabled = False
    End Sub
    Sub unlockall()
        cBx1.Enabled = True
        cBx2.Enabled = True
        tBx1.Enabled = True
        tBx2.Enabled = True
        tBx3.Enabled = True
    End Sub
    Sub setall()
        cBx1.Text = ""
        cBx2.Text = ""
        tBx1.Text = ""
        tBx2.Text = ""
        tBx3.Text = ""
    End Sub
    Sub updatecombo1()
        Call connect()
        Dim cd As New System.Data.SqlClient.SqlCommand("SELECT [Name],[NameID] FROM [RepairName] order by [Name]", cn)
        Dim adp As New System.Data.SqlClient.SqlDataAdapter(cd)
        Dim ds As New DataSet
        adp.Fill(ds)
        'ComboBox2.Items.Clear()
        cBx1.DisplayMember = "Name"
        cBx1.ValueMember = "NameID"
        cBx1.DataSource = ds.Tables(0)
    End Sub
    Sub updatecombo2()
        Call connect()
        Dim cd As New System.Data.SqlClient.SqlCommand("SELECT [RepairType],[RepairTypeID] FROM [RepairType] order by [RepairType]", cn)
        Dim adp As New System.Data.SqlClient.SqlDataAdapter(cd)
        Dim ds As New DataSet
        adp.Fill(ds)
        'ComboBox2.Items.Clear()
        cBx2.DisplayMember = "RepairType"
        cBx2.ValueMember = "RepairTypeID"
        cBx2.DataSource = ds.Tables(0)
    End Sub
    Sub updatecombo3()
        Call connect()
        Dim cd As New System.Data.SqlClient.SqlCommand("SELECT [Service],[ServiceID] FROM [Service] order by [Service]", cn)
        Dim adp As New System.Data.SqlClient.SqlDataAdapter(cd)
        Dim ds As New DataSet
        adp.Fill(ds)
        'ComboBox2.Items.Clear()
        cBx1.DisplayMember = "Service"
        cBx1.ValueMember = "ServiceID"
        cBx1.DataSource = ds.Tables(0)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        If cBx1.Enabled = True Then
            Dim str As String = "insert into MaintenanceTask (MainID, TypeID, PartCost, LaborCost, Total) values (" & (cBx1.SelectedValue.ToString()) & ", " & (cBx2.SelectedValue.ToString()) & ", " & CInt(tBx1.Text) & "," & CInt(tBx2.Text) & "," & CInt(tBx3.Text) & ")"
            Call connect()
            Dim cd As New System.Data.SqlClient.SqlCommand(str, cn)
            cd.Connection.Open()
            cd.ExecuteNonQuery()
            cd.Connection.Close()
            MsgBox(" New Task is added successfully ")
            Call lockall()
            Me.Close()
            Call IssueWorkOrder.listView2load()

        Else
            MsgBox(" Task is not added Try again ")

        End If

    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        AddService.Show()
        AddService.Visible = True
    End Sub

    Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged
        RadioButton1.Text = "Preventive"
    End Sub

    Private Sub RadioButton2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton2.CheckedChanged
        RadioButton2.Text = "Repair"
    End Sub

    Private Sub RadioButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.Click
        Call updatecombo3()
        Label3.Text = "Service"
        cBx2.Enabled = False
    End Sub

    Private Sub RadioButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton2.Click
        Call updatecombo1()
        Call updatecombo2()
        Label3.Text = "Repair"
        cBx2.Enabled = True
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Me.Close()
    End Sub
End Class
4

1 回答 1

0

您的主要问题是您的插入字符串。您不检查组合的值是否有效,并在 VB 项中的 NULL (Nothing) 上调用 ToString

   Dim str As String = "insert into MaintenanceTask (MainID, TypeID, PartCost, " & _
                       "LaborCost, Total) values (" & (cBx1.SelectedValue.ToString()) & _
                       ", " & (cBx2.SelectedValue.ToString()) & ", " & CInt(tBx1.Text) & _
                        "," & CInt(tBx2.Text) & "," & CInt(tBx3.Text) & ")"

如果 cBx1.SelectedValue 为 NULL,则不能在 NULL 对象上调用方法 (ToString),这是收到的 NullReferenceException。但是,您有一个更严重的问题,称为Sql Injection(请阅读文章)

   Dim str As String = "insert into MaintenanceTask (MainID, TypeID, PartCost, " & _
                       "LaborCost, Total) values (@main, @tp, @cost, @labcost, @tot)"

    Dim cd As New SqlCommand(str, cn)
    cd.Parameters.AddWithValue("@main", if(cbx1.SelectedValue == null, DBNull.Value, cbx1.SelectedValue.ToString)
    cd.Parameters.AddWithValue("@tp", if(cbx2.SelectedValue == null, DBNull.Value, cbx2.SelectedValue.ToString)
    cd.Parameters.AddWithValue("@cost", Convert.ToInt32(tBx1.Text))
    cd.Parameters.AddWithValue("@labcost", Convert.ToInt32(tBx2.Text))
    cd.Parameters.AddWithValue("@totale", Convert.ToInt32(tBx3.Text))
    cd.Connection.Open()
    cd.ExecuteNonQuery()
    cd.Connection.Close()
    MsgBox(" New Task is added successfully ")
    Call lockall()
    Me.Close()
    Call IssueWorkOrder.listView2load()

其他问题是文本框的整数转换。
如果输入不是一个有效的数值,你会得到一个错误,你需要在连接对象是稀缺资源之前进行一些错误处理,你应该确保在完成后关闭。您的代码缺少错误处理,如果出现错误,您的连接永远不会关闭。

于 2013-03-16T13:35:39.013 回答