查询不会更新SQL Server

时间:2016-01-19 19:20:00

标签: sql-server vb.net winforms

在下面的代码中,我的第二个查询不会插入SQL数据库,但第一个查询将更新。我可以复制查询(从我添加的msgbox进行测试)并将其粘贴到SQL Server Management Studio中,它将执行正常。我也没有从SQL获得任何错误消息,但我不确定该代码是否正确(它是从另一个源复制+粘贴)。另外,我可以简化代码以同时传递两个查询吗?

Dim Conn As New System.Data.SqlClient.SqlConnection         'sql server datastream connection
Dim Cmd As New System.Data.SqlClient.SqlCommand             'sql command vars
Dim SqlQuery As String                                      'string var used to hold various SQL queries
Dim data As System.Data.SqlClient.SqlDataReader             'datareader object variable
Dim MVDataset As New DataSet
Dim MVDatatable As DataTable
Dim MVDatarow As DataRow

Private Sub MVUpdateButton_Click(sender As Object, e As EventArgs) Handles MVUpdateButton.Click

  vbyn = MsgBox("Are you sure you want to update Tally Sheet Master Variables?" & vbCrLf & vbCrLf & "Changes to these variables will change the functionality of the Tally Sheet!", vbYesNo, )
  Try
    Select Case vbyn
      Case vbNo
        GoTo MVTableUpdateBypass
      Case vbYes
        'get new data from textboxes
        Vers = TextBox1.Text
        If TextBox2.Text = True Then
          Testing = 1
        Else
          Testing = 0
        End If
        FlatFeeCharge = TextBox3.Text
        PrepricingCharge = TextBox4.Text
        SendMailAcct = TextBox5.Text
        SendMailPW = TextBox6.Text
        TestingEmail = TextBox7.Text
        PrePricingEmail = TextBox8.Text
        ImperataEmail = TextBox9.Text

        'update existing active row to mark inactive
        SqlQuery = "Update MasterVars set Active = 0 where PKEY = " & PKEY & ";"
        MsgBox(SqlQuery)
        If Conn.State = ConnectionState.Closed Then
          Conn.ConnectionString = "Data Source=SQL01;Initial Catalog=TallySheet;Integrated Security=SSPI;"
        End If
        Conn.Open()
        Dim MVDataAdapter As New SqlDataAdapter(SqlQuery, Conn)
        Dim MVUpdateCommand As SqlCommand
        MVUpdateCommand = New SqlCommand(SqlQuery)
        MVDataAdapter.UpdateCommand = MVUpdateCommand

        'insert new active row
        SqlQuery = "Insert into MasterVars (Vers, Testing, FlatFeeCharge, PrePricingCharge, SendMailAcct, SendMailPW, TestingEmail, PrePricingEmail, ImperataEmail, DTS, UserName, Active) Values (" & "'" & Vers & "', " & Testing & ", '" & FlatFeeCharge & "'" & ", '" & PrepricingCharge & "'" & ", '" & SendMailAcct & "'" & ", '" & SendMailPW & "'" & ", '" & TestingEmail & "'" & ", '" & PrePricingEmail & "'" & ", '" & ImperataEmail & "'" & ", '" & Date.Now & "'," & "'QGDOMAIN\" & Environment.UserName & "'," & 1 & ");"
        MsgBox(SqlQuery)
        Dim MVInsertCommand As SqlCommand
        MVInsertCommand = New SqlCommand(SqlQuery)
        MVDataAdapter.InsertCommand = MVInsertCommand
        MVDataAdapter.Fill(MVDataset, "MasterVars")
      End Select
    Catch ex As SqlException
      Dim i As Integer
      Dim errormessages As String
      errormessages = ""
      For i = 0 To ex.Errors.Count - 1
        errormessages = errormessages & " " & ("Index #" & i.ToString() & ControlChars.NewLine _
                & "Message: " & ex.Errors(i).Message & ControlChars.NewLine _
                & "LineNumber: " & ex.Errors(i).LineNumber & ControlChars.NewLine _
                & "Source: " & ex.Errors(i).Source & ControlChars.NewLine _
                & "Procedure: " & ex.Errors(i).Procedure & ControlChars.NewLine)
      Next i
    Console.WriteLine(errorMessages.ToString())
  End Try

  'reload form with updated variables
  Conn.Close()
  Conn.Dispose()
MVTableUpdateBypass:
End Sub

1 个答案:

答案 0 :(得分:3)

SqlDataAdapter的Fill方法执行SelectCommand而不是UpdateCommandInsertCommand。在任何情况下,当您调用适配器的DeleteCommand方法时,都会执行这两个命令(以及Update)。 此外,Update方法运行命令,查找由SelectCommand检索的DataTable / DataSet中更改/添加/删除的行,并且仅适用于那些行。

但是您不需要SqlDataAdapter来执行您的两个查询。你应该简单地构造一个SqlCommand,两个文本用分号分隔并调用ExecuteNonQuery

SqlQuery = "Update MasterVars set Active = 0 where PKEY = @key;" & _
           "Insert into MasterVars (Vers, Testing, .....) VALUES (@p1, @o2, ....)"
Using Conn = New SqlConnection("Data Source=SQL01;......")
Using cmd = New SqlCommand(SqlQuery, Conn)
    Conn.Open()
    cmd.Parameters.Add("@key", SqlDbType.Int).Value = PKEY 
    cmd.Parameters.Add("@p1", SqlDbType.NVarChar).Value = vers 
    cmd.Parameters.Add("@p2", SqlDbType.Int).Value = testing
    ... and so on with other parameters .... 
    cmd.ExecuteNonQuery()
End Using
End Using

在这个不完整的例子中(要记下的参数太多)我将两个sql文本连接在一个字符串中,并使用参数占位符进行准备。然后我使用表所需的确切数据类型构建参数集合,最后调用ExecuteNonQuery来运行数据库端的所有内容。

请注意,不需要保留连接或命令等全局对象。创建局部变量总是更好,在完成后使用并销毁它。特别是连接和命令等一次性对象应始终在使用块

中创建