0

これは vb.net の私のコードです。挿入クエリを VB.net から SQL サーバーに渡すと、オブジェクト参照がインスタンス オブジェクトに設定されていないというクエリで例外が発生しました。SQL フィールドでは null が許可され、ID は自動インクリメントです。 . 私の仲間の 1 人は、レコード セットを使用してそのような状態を伝えると言いましたが、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 インジェクションと呼ばれるより深刻な問題があります(記事をお読みください)。

   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 に答える