可以有多个SqlCommand吗?

发布于 2024-12-27 06:46:59 字数 894 浏览 1 评论 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 吗?

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

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()

Is this possible to run 2 SqlCommand together??

Because after executed somehow the 2nd inside the loop did not execute or insert data.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

双马尾 2025-01-03 06:46:59

您没有 2 个 SqlCommand。

您有 1 个 SqlCommand,名为 cmd,它会执行多次。

做这样的事情很好,但是我会为您的 INSERT INTO record 提供 1 个 SqlCommand,为您的 INSERT INTO record_item 提供 1 个 SqlCommand。我认为这使得以后回顾代码时更容易理解。

无论哪种方式,使用这样的 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()

You don't have 2 SqlCommands.

You have 1 SqlCommand, called cmd, which is executed multiple times.

It is fine to do something like this, however I would have 1 SqlCommand for your INSERT INTO record, and 1 for your INSERT INTO record_item. I think this makes it much easier to understand when looking back at the code at a later date.

Either way, using a SqlCommand like this should not prevent it from executing, therefore I believe there is another issue with your scripting.


I've adapted your code so that it is split into 2 seperate SqlCommand objects, and the queries have been parameterized to prevent 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()
怎会甘心 2025-01-03 06:46:59

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

Dim cmd2 as SqlCommand

One command can only be used once.
If you want to use more than one command, declare a new cmd as

Dim cmd2 as SqlCommand
温柔一刀 2025-01-03 06:46:59

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

对命令使用参数也将使代码更易于理解和更安全,您应该尽可能使用 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

In order to ensure that either all statements complete successfully or that none do, you need to wrap your commands in a transaction.

Using parameters for the commands will also make the code more understandable and safer and you should use using statements where possible.

Also, performing the Select max recordid is a very bad idea (if you have multiple users), but I'll leave that for another time:

    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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文