Freigeben über


Verwenden mehrerer aktiver Resultsets (MARS)

SQL Server 2005 hat unterstützung für mehrere aktive Resultsets (MARS) in Anwendungen eingeführt, die auf das Datenbankmodul zugreifen. In früheren Versionen von SQL Server konnten Datenbankanwendungen nicht mehrere aktive Anweisungen für eine Verbindung verwalten. Bei Verwendung von SQL Server-Standardergebnissätzen musste die Anwendung alle Resultsets aus einem Batch verarbeiten oder abbrechen, bevor ein anderer Batch für diese Verbindung ausgeführt werden konnte. SQL Server 2005 hat ein neues Verbindungsattribute eingeführt, das Es Anwendungen ermöglicht, mehr als eine ausstehende Anforderung pro Verbindung zu haben und insbesondere mehr als ein aktives Standardergebnissatz pro Verbindung zu haben.

MARS vereinfacht das Anwendungsdesign mit den folgenden neuen Funktionen:

  • Anwendungen können mehrere Standardergebnissätze geöffnet haben und das Lesen daraus zwischenspeichern.

  • Anwendungen können andere Anweisungen (z. B. INSERT, UPDATE, DELETE und gespeicherte Prozeduraufrufe) ausführen, während Standardergebnissätze geöffnet sind.

Anwendungen, die MARS verwenden, werden die folgenden Richtlinien vorteilhaft finden:

  • Standardergebnissätze sollten für kurze oder kurze Resultsets verwendet werden, die von einzelnen SQL-Anweisungen generiert werden (SELECT, DML mit OUTPUT, RECEIVE, READ TEXT usw.).

  • Servercursor sollten für längere Oder große Resultsets verwendet werden, die von einzelnen SQL-Anweisungen generiert werden.

  • Immer am Ende der Ergebnisse für prozedurale Anforderungen lesen, unabhängig davon, ob sie Ergebnisse zurückgeben oder nicht, und für Batches, die mehrere Ergebnisse zurückgeben.

  • Verwenden Sie nach Möglichkeit API-Aufrufe, um Verbindungseigenschaften zu ändern und Transaktionen vor Transact-SQL Anweisungen zu verwalten.

  • In MARS ist der identitätsbezogene Identitätswechsel im Sitzungsbereich verboten, während gleichzeitige Batches ausgeführt werden.

Hinweis

Standardmäßig ist die MARS-Funktionalität nicht aktiviert. Um MARS beim Herstellen einer Verbindung mit SQL Server mit SQL Server Native Client zu verwenden, müssen Sie ihn speziell in einer Verbindungszeichenfolge aktivieren. Weitere Informationen finden Sie in den Abschnitten sql Server Native Client OLE DB-Anbieter und SQL Server Native Client ODBC-Treiberabschnitte weiter unten in diesem Thema.

Sql Server Native Client beschränkt nicht die Anzahl der aktiven Anweisungen für eine Verbindung.

Typische Anwendungen, die nicht mehr als einen einzelnen Multistatementbatch oder eine gespeicherte Prozedur gleichzeitig ausführen müssen, profitieren von MARS, ohne verstehen zu müssen, wie MARS implementiert wird. Anwendungen mit komplexeren Anforderungen müssen dies jedoch berücksichtigen.

MARS ermöglicht die verschachtelte Ausführung mehrerer Anforderungen innerhalb einer einzigen Verbindung. Das heißt, ein Batch kann ausgeführt werden, und innerhalb seiner Ausführung können andere Anforderungen ausgeführt werden. Beachten Sie jedoch, dass MARS in Bezug auf die Verzahnung definiert ist, nicht in Bezug auf die parallele Ausführung.

Die MARS-Infrastruktur ermöglicht es mehreren Batches, in einer interleavierten Weise auszuführen, obwohl die Ausführung nur an gut definierten Punkten umgeschaltet werden kann. Darüber hinaus müssen die meisten Anweisungen in einem Batch atomisch ausgeführt werden. Anweisungen, die Zeilen an den Client zurückgeben, die manchmal als Renditepunkte bezeichnet werden, dürfen die Ausführung vor Abschluss des Vorgangs zwischenspeichern, während Zeilen an den Client gesendet werden, z. B.:

  • AUSWÄHLEN

  • HOLEN

  • EMPFANGEN

Alle anderen Anweisungen, die als Teil einer gespeicherten Prozedur oder eines Batches ausgeführt werden, müssen bis zur Fertigstellung ausgeführt werden, bevor die Ausführung auf andere MARS-Anforderungen umgestellt werden kann.

Die genaue Art und Weise, in der batches die Ausführung von Stapeln durch eine Reihe von Faktoren beeinflusst wird, und es ist schwierig, die genaue Reihenfolge vorherzusagen, in der Befehle aus mehreren Batches, die Ertragspunkte enthalten, ausgeführt werden. Achten Sie darauf, unerwünschte Nebenwirkungen aufgrund der überlappenden Ausführung solcher komplexen Batches zu vermeiden.

Vermeiden Sie Probleme, indem Sie API-Aufrufe anstelle von Transact-SQL Anweisungen verwenden, um den Verbindungsstatus (SET, USE) und Transaktionen (BEGIN TRAN, COMMIT, ROLLBACK) zu verwalten, indem Sie diese Anweisungen nicht in Mehranweisungsbatches einschließen, die auch Ertragspunkte enthalten, und indem Sie die Ausführung solcher Batches serialisieren, indem alle Ergebnisse verwendet oder abgebrochen werden.

Hinweis

Eine Batch- oder gespeicherte Prozedur, die eine manuelle oder implizite Transaktion startet, wenn MARS aktiviert ist, muss die Transaktion abschließen, bevor der Batch beendet wird. Wenn dies nicht der Fall ist, setzt SQL Server alle Änderungen zurück, die von der Transaktion vorgenommen wurden, wenn der Batch abgeschlossen ist. Eine solche Transaktion wird von SQL Server als batchbezogene Transaktion verwaltet. Dies ist eine neue Art von Transaktion, die in SQL Server 2005 eingeführt wurde, um vorhandene gespeicherte gespeicherte Prozeduren zu ermöglichen, die verwendet werden können, wenn MARS aktiviert ist. Weitere Informationen zu Batch-bezogenen Transaktionen finden Sie unter Transaktionsanweisungen (Transact-SQL).

Ein Beispiel für die Verwendung von MARS aus ADO finden Sie unter Verwenden von ADO mit SQL Server Native Client.

SQL Server Native Client OLE DB-Anbieter

Der OLE DB-Anbieter von SQL Server Native Client unterstützt MARS durch das Hinzufügen der SSPROP_INIT_MARSCONNECTION Eigenschaft für die Datenquelleninitialisierung, die im DBPROPSET_SQLSERVERDBINIT-Eigenschaftensatz implementiert wird. Darüber hinaus wurde ein neues Verbindungszeichenfolgen-Schlüsselwort hinzugefügt MarsConn. Sie akzeptiert true oder false Werte; false ist der Standardwert.

Die Datenquelleneigenschaft DBPROP_MULTIPLECONNECTIONS standardmäßig auf VARIANT_TRUE festgelegt. Dies bedeutet, dass der Anbieter mehrere Verbindungen öffnet, um mehrere gleichzeitige Befehls- und Rowsetobjekte zu unterstützen. Wenn MARS aktiviert ist, kann SQL Server Native Client mehrere Befehls- und Rowsetobjekte für eine einzelne Verbindung unterstützen, sodass MULTIPLE_CONNECTIONS standardmäßig auf VARIANT_FALSE festgelegt ist.

Weitere Informationen zu Verbesserungen am DBPROPSET_SQLSERVERDBINIT Eigenschaftensatz finden Sie unter Initialisierungs- und Autorisierungseigenschaften.

SQL Server Native Client OLE DB-Anbieter (Beispiel)

In diesem Beispiel wird ein Datenquellenobjekt mithilfe des SQL Server Native OLE DB-Anbieters erstellt, und MARS wird mithilfe des DBPROPSET_SQLSERVERDBINIT-Eigenschaftssatzes aktiviert, bevor das Sitzungsobjekt erstellt wird.

#include <sqlncli.h>  
  
IDBInitialize *pIDBInitialize = NULL;  
IDBCreateSession *pIDBCreateSession = NULL;  
IDBProperties *pIDBProperties = NULL;  
  
// Create the data source object.  
hr = CoCreateInstance(CLSID_SQLNCLI10, NULL,  
   CLSCTX_INPROC_SERVER,  
   IID_IDBInitialize,   
    (void**)&pIDBInitialize);  
  
hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void**)&pIDBProperties);  
  
// Set the MARS property.  
DBPROP rgPropMARS;  
  
// The following is necessary since MARS is off by default.  
rgPropMARS.dwPropertyID = SSPROP_INIT_MARSCONNECTION;  
rgPropMARS.dwOptions = DBPROPOPTIONS_REQUIRED;  
rgPropMARS.dwStatus = DBPROPSTATUS_OK;  
rgPropMARS.colid = DB_NULLID;  
V_VT(&(rgPropMARS.vValue)) = VT_BOOL;  
V_BOOL(&(rgPropMARS.vValue)) = VARIANT_TRUE;  
  
// Create the structure containing the properties.  
DBPROPSET PropSet;  
PropSet.rgProperties = &rgPropMARS;  
PropSet.cProperties = 1;  
PropSet.guidPropertySet = DBPROPSET_SQLSERVERDBINIT;  
  
// Get an IDBProperties pointer and set the initialization properties.  
pIDBProperties->SetProperties(1, &PropSet);  
pIDBProperties->Release();  
  
// Initialize the data source object.  
hr = pIDBInitialize->Initialize();  
  
//Create a session object from a data source object.  
IOpenRowset * pIOpenRowset = NULL;  
hr = IDBInitialize->QueryInterface(IID_IDBCreateSession, (void**)&pIDBCreateSession));  
hr = pIDBCreateSession->CreateSession(  
   NULL,             // pUnkOuter  
   IID_IOpenRowset,  // riid  
  &pIOpenRowset ));  // ppSession  
  
// Create a rowset with a firehose mode cursor.  
IRowset *pIRowset = NULL;  
DBPROP rgRowsetProperties[2];  
  
// To get a firehose mode cursor request a   
// forward only read only rowset.  
rgRowsetProperties[0].dwPropertyID = DBPROP_IRowsetLocate;  
rgRowsetProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;  
rgRowsetProperties[0].dwStatus = DBPROPSTATUS_OK;  
rgRowsetProperties[0].colid = DB_NULLID;  
VariantInit(&(rgRowsetProperties[0].vValue));  
rgRowsetProperties[0].vValue.vt = VARIANT_BOOL;  
rgRowsetProperties[0].vValue.boolVal = VARIANT_FALSE;  
  
rgRowsetProperties[1].dwPropertyID = DBPROP_IRowsetChange;  
rgRowsetProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED;  
rgRowsetProperties[1].dwStatus = DBPROPSTATUS_OK;  
rgRowsetProperties[1].colid = DB_NULLID;  
VariantInit(&(rgRowsetProperties[1].vValue));  
rgRowsetProperties[1].vValue.vt = VARIANT_BOOL;  
rgRowsetProperties[1].vValue.boolVal = VARIANT_FALSE;  
  
DBPROPSET rgRowsetPropSet[1];  
rgRowsetPropSet[0].rgProperties = rgRowsetProperties  
rgRowsetPropSet[0].cProperties = 2  
rgRowsetPropSet[0].guidPropertySet = DBPROPSET_ROWSET;  
  
hr = pIOpenRowset->OpenRowset (NULL,  
   &TableID,  
   NULL,  
   IID_IRowset,  
   1,  
   rgRowsetPropSet  
   (IUnknown**)&pIRowset);  

ODBC-Treiber für SQL Server Native Client

Der SQL Server Native Client ODBC-Treiber unterstützt MARS durch Ergänzungen der Funktionen SQLSetConnectAttr und SQLGetConnectAttr . SQL_COPT_SS_MARS_ENABLED wurde hinzugefügt, um entweder SQL_MARS_ENABLED_YES oder SQL_MARS_ENABLED_NO zu akzeptieren, wobei SQL_MARS_ENABLED_NO die Standardeinstellung ist. Darüber hinaus wurde ein neues Verbindungszeichenfolgen-Schlüsselwort hinzugefügt Mars_Connection. Sie akzeptiert "Ja"- oder "Nein"-Werte; "nein" ist die Standardeinstellung.

SQL Server Native Client ODBC-Treiber (Beispiel)

In diesem Beispiel wird die SQLSetConnectAttr-Funktion verwendet, um MARS zu aktivieren, bevor die SQLDriverConnect-Funktion aufgerufen wird, um die Datenbank zu verbinden. Nachdem die Verbindung hergestellt wurde, werden zwei SQLExecDirect-Funktionen aufgerufen, um zwei separate Resultsets für dieselbe Verbindung zu erstellen.

#include <sqlncli.h>  
  
SQLSetConnectAttr(hdbc, SQL_COPT_SS_MARS_ENABLED, SQL_MARS_ENABLED_YES, SQL_IS_UINTEGER);  
SQLDriverConnect(hdbc, hwnd,   
   "DRIVER=SQL Server Native Client 10.0;  
   SERVER=(local);trusted_connection=yes;", SQL_NTS, szOutConn,   
   MAX_CONN_OUT, &cbOutConn, SQL_DRIVER_COMPLETE);  
  
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt1);  
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt2);  
  
// The 2nd execute would have failed with connection busy error if  
// MARS were not enabled.  
SQLExecDirect(hstmt1, L"SELECT * FROM Authors", SQL_NTS);  
SQLExecDirect(hstmt2, L"SELECT * FROM Titles", SQL_NTS);  
  
// Result set processing can interleave.  
SQLFetch(hstmt1);  
SQLFetch(hstmt2);  

Siehe auch

SQL Server Native Client-Funktionen
Verwenden von SQL Server-Standardergebnissätzen