Sprache
Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Vor der Einführung von MARS (Multiple Active Result Sets, mehrere aktive Resultsets) mussten Entwickler entweder mehrere Verbindungen oder serverseitige Cursor verwenden, um bestimmte Szenarien aufzulösen. Darüber hinaus waren gebundene Verbindungen (mit sp_getbindtoken und sp_bindsession) erforderlich, wenn mehrere Verbindungen in einer transaktionsalen Situation verwendet wurden. In den folgenden Szenarien wird gezeigt, wie eine MARS-fähige Verbindung anstelle mehrerer Verbindungen verwendet wird.
Verwenden mehrerer Befehle mit MARS
Die folgende Konsolenanwendung veranschaulicht die Verwendung zweier SqlDataReader-Objekte mit zwei SqlCommand-Objekten und einem einzelnen SqlConnection-Objekt bei aktiviertem MARS.
Beispiel
Im Beispiel wird eine einzige Verbindung mit der AdventureWorks Datenbank geöffnet. Dies SqlCommand erstellt den ersten SqlDataReader. Während der Code seine Ergebnisse liest, öffnet er einen zweiten Reader und verwendet Daten aus dem ersten Reader als Eingabe in die WHERE-Klausel der zweiten Abfrage.
Hinweis
Im folgenden Beispiel wird die Beispieldatenbank AdventureWorks verwendet, die in SQL Server enthalten ist. Bei der im Beispielcode bereitgestellten Verbindungszeichenfolge wird davon ausgegangen, dass die Datenbank auf dem lokalen Computer installiert und verfügbar ist. Ändern Sie die Verbindungszeichenfolge nach Bedarf für Ihre Umgebung.
Option Strict On
Option Explicit On
Imports System
Imports System.Data
Imports Microsoft.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 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 "..." +
"MultipleActiveResultSets=True";
}
}
Lesen und Aktualisieren von Daten mit MARS
MARS ermöglicht die Verwendung einer Verbindung sowohl für Lese- als auch für DML-Vorgänge (Data Manipulation Language, Datenbearbeitungssprache) mit mehr als einem ausstehenden Vorgang. Dieses Feature macht eine Anwendung zur Behandlung von Fehlern im Zusammenhang mit der Verbindungsauslastung überflüssig. Darüber hinaus kann MARS die Verwendung serverseitiger Cursor ersetzen, die im Allgemeinen mehr Ressourcen benötigen. Da mehrere Vorgänge mit einer einzigen Verbindung ausgeführt werden können, können sie denselben Transaktionskontext gemeinsam nutzen, wodurch die Notwendigkeit entfällt, die Systemspeicherprozeduren wie sp_getbindtoken und sp_bindsession zu verwenden.
Beispiel
Die folgende Konsolenanwendung verwendet zwei SqlDataReader Objekte, drei SqlCommand Objekte und ein SqlConnection Objekt mit aktivierter MARS-Funktion. Der erste Befehl ruft Anbieter ab, deren Bonitätsbewertung 5 ist. Für jede Hersteller-ID aus dem ersten Reader ruft der zweite Befehl die Produkte dieses Anbieters in den zweiten Reader ab. Der Code berechnet für jedes Produkt ein neues OnOrderQty und verwendet den dritten Befehl zum Aktualisieren ProductVendor. Der gesamte Prozess erfolgt innerhalb einer einzelnen Transaktion, die vom Code am Ende zurückgerollt wird.
Hinweis
Im folgenden Beispiel wird die Beispieldatenbank AdventureWorks verwendet, die in SQL Server enthalten ist. Bei der im Beispielcode bereitgestellten Verbindungszeichenfolge wird davon ausgegangen, dass die Datenbank auf dem lokalen Computer installiert und verfügbar ist. Ändern Sie die Verbindungszeichenfolge nach Bedarf für Ihre Umgebung.
Option Strict On
Option Explicit On
Imports System
Imports System.Data
Imports Microsoft.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 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 "..." +
"MultipleActiveResultSets=True";
}
}