2012-01-17 2 views
0
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 вместе?Возможно иметь несколько SqlCommand?

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

+0

Вы получаете ошибку? Вы пробовали отладку? Что происходит во втором 'cmd.ExecuteNonQuery'? – Curt

+0

ничего не случилось, после отладки и попытаться вставить некоторые данные, но база данных остается пустой, только 1 sqlcommand работал – user1151874

+0

Имеет ли ваш DataGrid строки? –

ответ

2

У вас нет 2 SqlCommands.

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

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

В любом случае использование SqlCommand, как это, не должно препятствовать его выполнению, поэтому я считаю, что есть еще одна проблема с вашими сценариями.


Я адаптировать свой код так, чтобы он разделен на 2 отдельных объектов SqlCommand и запросы были настроены параметры для предотвращения SQL Injection:

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

OP имеет только одну переменную SqlCommand, но фактически создает несколько объектов SqlCommand * *. Есть два новых назначения SqlCommand(), а один - в цикле. –

+0

Это правда, но новый объект SqlCommand может быть просто изменением в CommandText, так как все остальное остается неизменным. – Curt

+0

Да, абсолютно ... но ваш ответ говорит, что у него только один SqlCommand. –

0

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

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

Кроме того, выполнение Выбрать максимальное 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 
+0

это код как-то тоже не работает, как вы сказали, либо все завершено, либо нет. – user1151874

+0

@ user1151874: Есть ли исключения? Я обновил файл insert_item, чтобы использовать другой формат запроса в случае, если это проблема. –

+0

не исключение, просто не знаю, где пошло не так .. – user1151874

0

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

Dim cmd2 as SqlCommand 
Смежные вопросы