Возможно ли иметь несколько SqlCommand? - PullRequest
0 голосов
/ 17 января 2012
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 вместе ??

Поскольку после выполнения каким-либо образом 2-й цикл внутри не выполнял или не вставлял данные.

Ответы [ 3 ]

2 голосов
/ 17 января 2012

У вас нет 2 SqlCommands.

У вас есть 1 SqlCommand, называемый cmd, который выполняется несколько раз.

Можно сделать что-то подобное, однако ябудет иметь 1 SqlCommand для вашего INSERT INTO record и 1 для вашего INSERT INTO record_item.Я думаю, что это облегчает понимание, если оглянуться на код позже.

В любом случае, использование такой 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()
0 голосов
/ 18 января 2012

Одна команда может быть использована только один раз. Если вы хотите использовать более одной команды, объявите новый cmd как

Dim cmd2 as SqlCommand
0 голосов
/ 17 января 2012

Чтобы убедиться, что все операторы завершены успешно или ни один из них не выполнен, вам нужно заключить команды в транзакцию.

Использование параметров для команд также сделает код более понятным и безопасным, и выследует использовать операторы там, где это возможно.

Также выполнение 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
...