在下面的代码中,我的第二个查询不会插入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
答案 0 :(得分:3)
SqlDataAdapter的Fill方法执行SelectCommand
而不是UpdateCommand
或InsertCommand
。在任何情况下,当您调用适配器的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
来运行数据库端的所有内容。
请注意,不需要保留连接或命令等全局对象。创建局部变量总是更好,在完成后使用并销毁它。特别是连接和命令等一次性对象应始终在使用块
中创建