Sdílet prostřednictvím


Manipulace s daty

Stáhnout ADO.NET

Před zavedením několika sad aktivních výsledků (MARS) museli vývojáři k řešení určitých scénářů použít buď více připojení, nebo kurzory na straně serveru. Kromě toho, když bylo v transakční situaci použito více připojení, vyžadovala se svázaná připojení (s sp_getbindtoken a sp_bindsession). Následující scénáře ukazují, jak místo více připojení používat připojení s podporou MARS.

Použití více příkazů s MARS

Následující konzolová aplikace ukazuje, jak používat dva SqlDataReader objekty se dvěma SqlCommand objekty a jeden SqlConnection objekt s povoleným MARS.

Example

Příklad otevře jedno připojení k databázi AdventureWorks . Pomocí objektu SqlCommand se SqlDataReader vytvoří objekt. Při použití čtečky se otevře sekunda SqlDataReader s použitím dat z prvního SqlDataReader jako vstupu do klauzule WHERE pro druhého čtenáře.

Poznámka:

Následující příklad používá ukázkovou databázi AdventureWorks , která je součástí SQL Serveru. Připojovací řetězec uvedený v ukázkovém kódu předpokládá, že je databáze nainstalovaná a dostupná v místním počítači. Podle potřeby upravte připojovací řetězec pro vaše prostředí.

using System;  
using System.Data;  
using Microsoft.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 "Data Source=(local);Integrated Security=SSPI;" +   
      "Initial Catalog=AdventureWorks;MultipleActiveResultSets=True";  
  }  
}  

Čtení a aktualizace dat pomocí MARS

MARS umožňuje používat připojení pro operace čtení i operace jazyka DML (Data Manipulat Language) s více než jednou čekající operací. Tato funkce eliminuje potřebu aplikace řešit chyby zaneprázdnění připojení. Kromě toho může MARS nahradit uživatele kurzorů na straně serveru, které obecně spotřebovávají více prostředků. Vzhledem k tomu, že na jednom připojení může fungovat více operací, můžou sdílet stejný kontext transakce, což eliminuje potřebu používat sp_getbindtoken a sp_bindsession systémových uložených procedur.

Example

Následující konzolová aplikace ukazuje, jak používat dva SqlDataReader objekty se třemi SqlCommand objekty a jeden SqlConnection objekt s povoleným MARS. První objekt příkazu načte seznam dodavatelů, jejichž rating je 5. Druhý objekt příkazu používá ID dodavatele poskytnutého z objektu SqlDataReader k načtení sekundy SqlDataReader se všemi produkty pro konkrétního dodavatele. Každý záznam o produktu je navštíven druhým SqlDataReader. Provede se výpočet, který určí, co má být nový OnOrderQty . Třetí objekt příkazu se pak použije k aktualizaci tabulky ProductVendor novou hodnotou. Celý proces probíhá v rámci jedné transakce, která se vrátí zpět na konec.

Poznámka:

Následující příklad používá ukázkovou databázi AdventureWorks , která je součástí SQL Serveru. Připojovací řetězec uvedený v ukázkovém kódu předpokládá, že je databáze nainstalovaná a dostupná v místním počítači. Podle potřeby upravte připojovací řetězec pro vaše prostředí.

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Data;  
using Microsoft.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 "Data Source=(local);Integrated Security=SSPI;" +   
    "Initial Catalog=AdventureWorks;" +   
    "MultipleActiveResultSets=True";  
  }  
}  

Další kroky