Bagikan melalui


Memanipulasi data

Sebelum pengenalan Beberapa Rangkaian Hasil Aktif (MARS), pengembang harus menggunakan beberapa koneksi atau kursor sisi server untuk menentukan skenario tertentu. Selain itu, ketika beberapa koneksi digunakan dalam situasi transaksi, koneksi terikat (dengan sp_getbindtoken dan sp_bindsession) diperlukan. Skenario berikut menunjukkan cara menggunakan koneksi dengan MARS yang diaktifkan, bukan beberapa koneksi.

Menggunakan Beberapa Perintah dengan MARS

Aplikasi Konsol berikut menunjukkan cara menggunakan dua SqlDataReader objek dengan dua SqlCommand objek dan satu SqlConnection objek dengan MARS diaktifkan.

Contoh

Contoh membuka satu koneksi ke database AdventureWorks. Menggunakan SqlCommandobjek , sebuah SqlDataReader dibuat. Saat pembaca digunakan, satu detik SqlDataReader dibuka, menggunakan data dari SqlDataReader yang pertama sebagai input untuk klausul WHERE untuk pembaca kedua.

Catatan

Contoh berikut menggunakan contoh database AdventureWorks yang disertakan dengan SQL Server. String koneksi yang disediakan dalam kode sampel mengasumsikan database dipasang dan tersedia di komputer lokal. Ubah string koneksi seperlunya untuk lingkungan Anda.

Option Strict On
Option Explicit On

Imports System
Imports System.Data
Imports System.Data.SqlClient
Module Module1
  Sub Main()
    ' By default, MARS is disabled when connecting
    ' to a MARS-enabled host.
    ' It must be enabled in the connection string.
    Dim connectionString As String = GetConnectionString()

    Dim vendorID As Integer

    Dim vendorCmd As SqlCommand
    Dim productCmd As SqlCommand
    Dim productReader As SqlDataReader

    Dim vendorSQL As String = & _
      "SELECT VendorId, Name FROM Purchasing.Vendor"
    Dim productSQL As String = _
        "SELECT Production.Product.Name FROM Production.Product " & _
        "INNER JOIN Purchasing.ProductVendor " & _
        "ON Production.Product.ProductID = " & _
        "Purchasing.ProductVendor.ProductID " & _
        "WHERE Purchasing.ProductVendor.VendorID = @VendorId"

    Using awConnection As New SqlConnection(connectionString)
      vendorCmd = New SqlCommand(vendorSQL, awConnection)
      productCmd = New SqlCommand(productSQL, awConnection)
      productCmd.Parameters.Add("@VendorId", SqlDbType.Int)

      awConnection.Open()
      Using vendorReader As SqlDataReader = vendorCmd.ExecuteReader()
        While vendorReader.Read()
          Console.WriteLine(vendorReader("Name"))

          vendorID = CInt(vendorReader("VendorId"))

          productCmd.Parameters("@VendorId").Value = vendorID

          ' The following line of code requires
          ' a MARS-enabled connection.
          productReader = productCmd.ExecuteReader()
          Using productReader
            While productReader.Read()
              Console.WriteLine("  " & CStr(productReader("Name")))
            End While
          End Using
        End While
      End Using
    End Using

    Console.WriteLine("Press any key to continue")
    Console.ReadLine()
  End Sub

  Function GetConnectionString() As String
    ' To avoid storing the connection string in your code,
    ' you can retrieve it from a configuration file.
    Return "..." & _
      "MultipleActiveResultSets=True"
  End Function
End Module
using System;
using System.Data;
using System.Data.SqlClient;

class Class1
{
static void Main()
{
  // By default, MARS is disabled when connecting
  // to a MARS-enabled host.
  // It must be enabled in the connection string.
  string connectionString = GetConnectionString();

  int vendorID;
  SqlDataReader productReader = null;
  string vendorSQL =
    "SELECT VendorId, Name FROM Purchasing.Vendor";
  string productSQL =
    "SELECT Production.Product.Name FROM Production.Product " +
    "INNER JOIN Purchasing.ProductVendor " +
    "ON Production.Product.ProductID = " +
    "Purchasing.ProductVendor.ProductID " +
    "WHERE Purchasing.ProductVendor.VendorID = @VendorId";

  using (SqlConnection awConnection =
    new SqlConnection(connectionString))
  {
    SqlCommand vendorCmd = new SqlCommand(vendorSQL, awConnection);
    SqlCommand productCmd =
      new SqlCommand(productSQL, awConnection);

    productCmd.Parameters.Add("@VendorId", SqlDbType.Int);

    awConnection.Open();
    using (SqlDataReader vendorReader = vendorCmd.ExecuteReader())
    {
      while (vendorReader.Read())
      {
        Console.WriteLine(vendorReader["Name"]);

        vendorID = (int)vendorReader["VendorId"];

        productCmd.Parameters["@VendorId"].Value = vendorID;
        // The following line of code requires
        // a MARS-enabled connection.
        productReader = productCmd.ExecuteReader();
        using (productReader)
        {
          while (productReader.Read())
          {
            Console.WriteLine("  " +
              productReader["Name"].ToString());
          }
        }
      }
  }
      Console.WriteLine("Press any key to continue");
      Console.ReadLine();
    }
  }
  private static string GetConnectionString()
  {
    // To avoid storing the connection string in your code,
    // you can retrieve it from a configuration file.
    return "..." +
      "MultipleActiveResultSets=True";
  }
}

Membaca dan Memperbarui Data dengan MARS

MARS memungkinkan koneksi digunakan untuk operasi pembacaan dan operasi bahasa manipulasi data (DML) dengan lebih dari satu operasi yang tertunda. Fitur ini menghilangkan kebutuhan aplikasi akan penanganan kesalahan koneksi-sibuk. Selain itu, MARS dapat menggantikan penggunaan kursor sisi server, yang umumnya menggunakan lebih banyak sumber daya. Akhirnya, karena beberapa operasi dapat dijalankan pada satu koneksi, maka dapat berbagi konteks transaksi yang sama, yang menghilangkan kebutuhan untuk menggunakan prosedur tersimpan sistem sp_getbindtoken dan sp_bindsession.

Contoh

Aplikasi Konsol berikut menunjukkan cara menggunakan dua objek SqlDataReader dengan tiga objek SqlCommand dan satu objek SqlConnection dengan MARS diaktifkan. Objek perintah pertama mengambil daftar vendor yang nilai kreditnya adalah 5. Objek perintah kedua menggunakan ID vendor yang disediakan dari SqlDataReader untuk memuat SqlDataReader yang kedua dengan semua produk untuk vendor tertentu. Setiap rekaman produk dikunjungi oleh SqlDataReader yang kedua. Penghitungan dilakukan untuk menentukan OnOrderQty baru yang seharusnya. Objek perintah ketiga kemudian digunakan untuk memperbarui tabel ProductVendor dengan nilai baru. Seluruh proses ini terjadi dalam satu transaksi, yang akhirnya digulung balik.

Catatan

Contoh berikut menggunakan contoh database AdventureWorks yang disertakan dengan SQL Server. String koneksi yang disediakan dalam kode sampel mengasumsikan database dipasang dan tersedia di komputer lokal. Ubah string koneksi seperlunya untuk lingkungan Anda.

Option Strict On
Option Explicit On

Imports System
Imports System.Data
Imports System.Data.SqlClient

Module Module1

  Sub Main()
    ' By default, MARS is disabled when connecting
    ' to a MARS-enabled host.
    ' It must be enabled in the connection string.
    Dim connectionString As String = GetConnectionString()

    Dim updateTx As SqlTransaction
    Dim vendorCmd As SqlCommand
    Dim prodVendCmd As SqlCommand
    Dim updateCmd As SqlCommand

    Dim prodVendReader As SqlDataReader

    Dim vendorID As Integer
    Dim productID As Integer
    Dim minOrderQty As Integer
    Dim maxOrderQty As Integer
    Dim onOrderQty As Integer
    Dim recordsUpdated As Integer
    Dim totalRecordsUpdated As Integer

    Dim vendorSQL As String = _
        "SELECT VendorID, Name FROM Purchasing.Vendor " & _
        "WHERE CreditRating = 5"
    Dim prodVendSQL As String = _
        "SELECT ProductID, MaxOrderQty, MinOrderQty, OnOrderQty " & _
        "FROM Purchasing.ProductVendor " & _
        "WHERE VendorID = @VendorID"
    Dim updateSQL As String = _
        "UPDATE Purchasing.ProductVendor " & _
        "SET OnOrderQty = @OrderQty " & _
        "WHERE ProductID = @ProductID AND VendorID = @VendorID"

    Using awConnection As New SqlConnection(connectionString)
      awConnection.Open()
      updateTx = awConnection.BeginTransaction()

      vendorCmd = New SqlCommand(vendorSQL, awConnection)
      vendorCmd.Transaction = updateTx

      prodVendCmd = New SqlCommand(prodVendSQL, awConnection)
      prodVendCmd.Transaction = updateTx
      prodVendCmd.Parameters.Add("@VendorId", SqlDbType.Int)

      updateCmd = New SqlCommand(updateSQL, awConnection)
      updateCmd.Transaction = updateTx
      updateCmd.Parameters.Add("@OrderQty", SqlDbType.Int)
      updateCmd.Parameters.Add("@ProductID", SqlDbType.Int)
      updateCmd.Parameters.Add("@VendorID", SqlDbType.Int)

      Using vendorReader As SqlDataReader = vendorCmd.ExecuteReader()
        While vendorReader.Read()
          Console.WriteLine(vendorReader("Name"))

          vendorID = CInt(vendorReader("VendorID"))
          prodVendCmd.Parameters("@VendorID").Value = vendorID
          prodVendReader = prodVendCmd.ExecuteReader()

          Using prodVendReader
            While (prodVendReader.Read)
              productID = CInt(prodVendReader("ProductID"))

              If IsDBNull(prodVendReader("OnOrderQty")) Then
                minOrderQty = CInt(prodVendReader("MinOrderQty"))
                onOrderQty = minOrderQty
              Else
                maxOrderQty = CInt(prodVendReader("MaxOrderQty"))
                onOrderQty = CInt(maxOrderQty / 2)
              End If

              updateCmd.Parameters("@OrderQty").Value = onOrderQty
              updateCmd.Parameters("@ProductID").Value = productID
              updateCmd.Parameters("@VendorID").Value = vendorID

              recordsUpdated = updateCmd.ExecuteNonQuery()
              totalRecordsUpdated += recordsUpdated
            End While
          End Using
        End While
      End Using

      Console.WriteLine("Total Records Updated: " & _
        CStr(totalRecordsUpdated))
      updateTx.Rollback()
      Console.WriteLine("Transaction Rolled Back")
    End Using

    Console.WriteLine("Press any key to continue")
    Console.ReadLine()

  End Sub

  Function GetConnectionString() As String
    ' To avoid storing the connection string in your code,
    ' you can retrieve it from a configuration file.
    Return "..." & _
      "MultipleActiveResultSets=True"
  End Function
End Module
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

class Program
{
static void Main()
{
  // By default, MARS is disabled when connecting
  // to a MARS-enabled host.
  // It must be enabled in the connection string.
  string connectionString = GetConnectionString();

  SqlTransaction updateTx = null;
  SqlCommand vendorCmd = null;
  SqlCommand prodVendCmd = null;
  SqlCommand updateCmd = null;

  SqlDataReader prodVendReader = null;

  int vendorID = 0;
  int productID = 0;
  int minOrderQty = 0;
  int maxOrderQty = 0;
  int onOrderQty = 0;
  int recordsUpdated = 0;
  int totalRecordsUpdated = 0;

  string vendorSQL =
      "SELECT VendorID, Name FROM Purchasing.Vendor " +
      "WHERE CreditRating = 5";
  string prodVendSQL =
      "SELECT ProductID, MaxOrderQty, MinOrderQty, OnOrderQty " +
      "FROM Purchasing.ProductVendor " +
      "WHERE VendorID = @VendorID";
  string updateSQL =
      "UPDATE Purchasing.ProductVendor " +
      "SET OnOrderQty = @OrderQty " +
      "WHERE ProductID = @ProductID AND VendorID = @VendorID";

  using (SqlConnection awConnection =
    new SqlConnection(connectionString))
  {
    awConnection.Open();
    updateTx = awConnection.BeginTransaction();

    vendorCmd = new SqlCommand(vendorSQL, awConnection);
    vendorCmd.Transaction = updateTx;

    prodVendCmd = new SqlCommand(prodVendSQL, awConnection);
    prodVendCmd.Transaction = updateTx;
    prodVendCmd.Parameters.Add("@VendorId", SqlDbType.Int);

    updateCmd = new SqlCommand(updateSQL, awConnection);
    updateCmd.Transaction = updateTx;
    updateCmd.Parameters.Add("@OrderQty", SqlDbType.Int);
    updateCmd.Parameters.Add("@ProductID", SqlDbType.Int);
    updateCmd.Parameters.Add("@VendorID", SqlDbType.Int);

    using (SqlDataReader vendorReader = vendorCmd.ExecuteReader())
    {
      while (vendorReader.Read())
      {
        Console.WriteLine(vendorReader["Name"]);

        vendorID = (int) vendorReader["VendorID"];
        prodVendCmd.Parameters["@VendorID"].Value = vendorID;
        prodVendReader = prodVendCmd.ExecuteReader();

        using (prodVendReader)
        {
          while (prodVendReader.Read())
          {
            productID = (int) prodVendReader["ProductID"];

            if (prodVendReader["OnOrderQty"] == DBNull.Value)
            {
              minOrderQty = (int) prodVendReader["MinOrderQty"];
              onOrderQty = minOrderQty;
            }
            else
            {
              maxOrderQty = (int) prodVendReader["MaxOrderQty"];
              onOrderQty = (int)(maxOrderQty / 2);
            }

            updateCmd.Parameters["@OrderQty"].Value = onOrderQty;
            updateCmd.Parameters["@ProductID"].Value = productID;
            updateCmd.Parameters["@VendorID"].Value = vendorID;

            recordsUpdated = updateCmd.ExecuteNonQuery();
            totalRecordsUpdated += recordsUpdated;
          }
        }
      }
    }
    Console.WriteLine("Total Records Updated: " +
      totalRecordsUpdated.ToString());
    updateTx.Rollback();
    Console.WriteLine("Transaction Rolled Back");
  }

  Console.WriteLine("Press any key to continue");
  Console.ReadLine();
}
private static string GetConnectionString()
{
  // To avoid storing the connection string in your code,
  // you can retrieve it from a configuration file.
  return "..." +
    "MultipleActiveResultSets=True";
  }
}

Lihat juga