可能有多个SqlCommand?

时间:2012-01-17 17:17:38

标签: sql vb.net sqlcommand

Dim conn As New SqlConnection("Database=Clinic_Management_System;Data Source=.\SQLExpress;Integrated Security=True;AttachDBFilename=|DataDirectory|Clinic Management System.mdf")
Dim cmd As SqlCommand
Dim dr As SqlDataReader
conn.Open()
cmd = New SqlCommand("INSERT INTO record([PatientID],[Prescription],[VisitDate]) Values ('" & PatientIDTextBox.Text & "','" & txtPrescription.Text & "',GetDate()) ", conn)
cmd.ExecuteNonQuery()

For cn As Integer = 0 To DataGridView1.RowCount - 1
    cmd = New SqlCommand("INSERT INTO record_item([RecordID],[ItemID],[Amount]) Values ( (SELECT MAX(RecordID) FROM record)," & DataGridView1.Rows(cn).Cells(0).Value & "," & DataGridView1.Rows(cn).Cells(2).Value & ")", conn)
    cmd.ExecuteNonQuery()

Next
conn.Close()

这可以一起运行2 SqlCommand吗?

因为在以某种方式执行后,循环内的第二个没有执行或插入数据。

3 个答案:

答案 0 :(得分:2)

你没有2个SqlCommands。

你有一个名为cmd的SqlCommand,它被执行多次。

可以这样做,但是我的INSERT INTO record会有1个SqlCommand,INSERT INTO record_item会有1个。我认为这使得在以后回顾代码时更容易理解。

无论哪种方式,使用像这样的SqlCommand不应该阻止它执行,因此我相信你的脚本还有另一个问题。


我已经调整了您的代码,以便将其拆分为2个单独的SqlCommand对象,并且已对参数进行参数化以防止SQL注入:

Dim conn As New SqlConnection("Database=Clinic_Management_System;Data Source=.\SQLExpress;Integrated Security=True;AttachDBFilename=|DataDirectory|Clinic Management System.mdf")

Dim cmdRecord As New SqlCommand("INSERT INTO record ([PatientID],[Prescription],[VisitDate]) Values (@PatientID, @Prescription, GETDATE())", conn)
cmdRecord.Parameters.Add("@PatientID", SqlDbType.Int).Value = PatientIDTextBox.Text
cmdRecord.Parameters.Add("@Prescription", SqlDbType.NVarChar).Value = txtPrescription.Text

Dim cmdRecordItem As New SqlCommand("INSERT INTO record_item([RecordID],[ItemID],[Amount]) Values ( (SELECT MAX(RecordID) FROM record),@ItemID,@AmountID)", conn)
cmdRecordItem.Parameters.Add("@ItemID", SqlDbType.Int)
cmdRecordItem.Parameters.Add("@Amount", SqlDbType.Decimal)

Dim dr As SqlDataReader
conn.Open()

cmdRecord.ExecuteNonQuery()

For cn As Integer = 0 To DataGridView1.RowCount - 1
    cmdRecordItem.Parameters("@ItemID").Value = DataGridView1.Rows(cn).Cells(0).Value
    cmdRecordItem.Parameters("@Amount").Value = DataGridView1.Rows(cn).Cells(2).Value

    cmdRecordItem.ExecuteNonQuery()

Next
conn.Close()

答案 1 :(得分:0)

为了确保所有语句都成功完成或者没有完成,您需要将命令包装在事务中。

使用命令参数也可以使代码更易理解和更安全,并且应尽可能使用using语句。

另外,执行Select max recordid是一个非常糟糕的主意(如果你有多个用户),但我会将其留下另一次:

    Using conn As New SqlConnection("Database=Clinic_Management_System;Data Source=.\SQLExpress;Integrated Security=True;AttachDBFilename=|DataDirectory|Clinic Management System.mdf")
        Dim cmdRecord As SqlCommand
        Dim cmdRecordItem As SqlCommand
        Dim oTran As SqlTransaction = Nothing

        conn.Open()
        Try
            cmdRecord = New SqlCommand("INSERT INTO record([PatientID],[Prescription],[VisitDate]) Values (@PatientID, @Prescription, GetDate())", conn)
            cmdRecord.Parameters.AddWithValue("@PatientID", PatientIDTextBox.Text)
            cmdRecord.Parameters.AddWithValue("@Prescription", txtPrescription.Text)

            cmdRecordItem = New SqlCommand("INSERT INTO record_item([RecordID],[ItemID],[Amount]) SELECT ISNULL(MAX(RecordID), 0), @ItemID, @Amount FROM record", conn)
            cmdRecordItem.Parameters.Add("@ItemId")
            cmdRecordItem.Parameters.Add("@Amount")

            oTran = conn.BeginTransaction

            cmdRecord.ExecuteNonQuery()

            For Each oRow As DataGridViewRow In DataGridView1
                cmdRecordItem.Parameters("@ItemId").Value = oRow.Cells(0).Value
                cmdRecordItem.Parameters("@Amount").Value = oRow.Cells(2).Value

                cmdRecordItem.ExecuteNonQuery()
            Next

            oTran.Commit()
        Catch
            If oTran IsNot Nothing Then
                oTran.Rollback()
            End If

            Throw
        Finally
            conn.Close()
        End Try
    End Using

答案 2 :(得分:0)

一个命令只能使用一次。 如果要使用多个命令,请将新cmd声明为

Dim cmd2 as SqlCommand