SQLSetPos-Funktion

Konformität
Version eingeführt: ODBC 1.0-Standardkonformität: ODBC

Zusammenfassung
SQLSetPos legt die Cursorposition in einem Rowset fest und ermöglicht es einer Anwendung, Daten im Rowset zu aktualisieren oder Daten im Resultset zu aktualisieren oder zu löschen.

Syntax

  
SQLRETURN SQLSetPos(  
      SQLHSTMT        StatementHandle,  
      SQLSETPOSIROW   RowNumber,  
      SQLUSMALLINT    Operation,  
      SQLUSMALLINT    LockType);  

Argumente

StatementHandle
[Eingabe] Anweisungshandle.

RowNumber
[Eingabe] Position der Zeile im Rowset, für die der mit dem Argument Operation angegebene Vorgang ausgeführt werden soll. Wenn RowNumber 0 ist, gilt der Vorgang für jede Zeile im Rowset.

Weitere Informationen finden Sie unter "Kommentare".

Vorgang
[Eingabe] Auszuführende Operation:

SQL_POSITION SQL_REFRESH SQL_UPDATE SQL_DELETE

Hinweis

Der SQL_ADD Wert für das Argument Operation ist für ODBC 3.x veraltet. ODBC 3.x-Treiber müssen aus Gründen der Abwärtskompatibilität SQL_ADD unterstützen. Diese Funktionalität wurde durch einen Aufruf von SQLBulkOperations durch einen Vorgang von SQL_ADD ersetzt. Wenn eine ODBC 3.x-Anwendung mit einem ODBC 2.x-Treiber arbeitet, ordnet der Treiber-Manager einen Aufruf von SQLBulkOperations mit einem Vorgang von SQL_ADD sqlSetPos mit einem Vorgang von SQL_ADD zu.

Weitere Informationen finden Sie unter "Kommentare".

LockType
[Eingabe] Gibt an, wie die Zeile gesperrt wird, nachdem der im Argument Operation angegebene Vorgang ausgeführt wurde.

SQL_LOCK_NO_CHANGE SQL_LOCK_EXCLUSIVE SQL_LOCK_UNLOCK

Weitere Informationen finden Sie unter "Kommentare".

Gibt zurück

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR oder SQL_INVALID_HANDLE.

Diagnose

Wenn SQLSetPos SQL_ERROR oder SQL_SUCCESS_WITH_INFO zurückgibt, kann ein zugeordneter SQLSTATE-Wert abgerufen werden, indem SQLGetDiagRec mit einem HandleType von SQL_HANDLE_STMT und einem Handle von StatementHandle aufgerufen wird. In der folgenden Tabelle sind die SQLSTATE-Werte aufgeführt, die häufig von SQLSetPos zurückgegeben werden, und die einzelnen Werte werden im Kontext dieser Funktion erläutert. die Notation "(DM)" steht vor den Beschreibungen von SQLSTATEs, die vom Treiber-Manager zurückgegeben werden. Der Rückgabecode, der jedem SQLSTATE-Wert zugeordnet ist, ist SQL_ERROR, sofern nicht anders angegeben.

Für alle SQLSTATEs, die SQL_SUCCESS_WITH_INFO oder SQL_ERROR zurückgeben können (mit Ausnahme von 01xxx SQLSTATEs), wird SQL_SUCCESS_WITH_INFO zurückgegeben, wenn ein Fehler für eine oder mehrere Zeilen eines Mehrzeilenvorgangs auftritt, und SQL_ERROR zurückgegeben wird, wenn bei einem Einzeilenvorgang ein Fehler auftritt.

SQLSTATE Fehler BESCHREIBUNG
01000 Allgemeine Warnung Treiberspezifische Informationsmeldung. (Funktion gibt SQL_SUCCESS_WITH_INFO zurück.)
01001 Cursorvorgangskonflikt Das Argument Operation wurde SQL_DELETE oder SQL_UPDATE, und es wurden keine Zeilen oder mehrere Zeilen gelöscht oder aktualisiert. (Weitere Informationen zu Updates für mehr als eine Zeile finden Sie in der Beschreibung des SQL_ATTR_SIMULATE_CURSOR-Attributs in SQLSetStmtAttr.) (Funktion gibt SQL_SUCCESS_WITH_INFO zurück.)

Das Argument Operation wurde SQL_DELETE oder SQL_UPDATE, und der Vorgang ist aufgrund der optimistischen Parallelität fehlgeschlagen. (Funktion gibt SQL_SUCCESS_WITH_INFO zurück.)
01004 Rechtes Abschneiden von Zeichenfolgendaten Das Argument Operation wurde SQL_REFRESH, und Zeichenfolgen- oder Binärdaten, die für eine Spalte oder Spalten mit einem Datentyp von SQL_C_CHAR oder SQL_C_BINARY zurückgegeben wurden, führten zum Abschneiden von binärdaten ohne oder ungleich NULL.
01S01 Fehler in Zeile Das Argument RowNumber war 0, und in einer oder mehreren Zeilen ist beim Ausführen des mit dem Argument Operation angegebenen Vorgangs ein Fehler aufgetreten.

(SQL_SUCCESS_WITH_INFO wird zurückgegeben, wenn ein Fehler für eine oder mehrere, aber nicht alle Zeilen eines Mehrzeilenvorgangs auftritt und SQL_ERROR zurückgegeben wird, wenn bei einem einzeilenigen Vorgang ein Fehler auftritt.)

(Dieser SQLSTATE-Wert wird nur zurückgegeben, wenn SQLSetPos nach SQLExtendedFetch aufgerufen wird, wenn der Treiber ein ODBC 2.x-Treiber ist und die Cursorbibliothek nicht verwendet wird.)
01S07 Bruchkürzung Das Argument Operation wurde SQL_REFRESH, der Datentyp des Anwendungspuffers wurde nicht SQL_C_CHAR oder SQL_C_BINARY, und die daten, die für eine oder mehrere Spalten an Anwendungspuffer zurückgegeben wurden, wurden abgeschnitten. Bei numerischen Datentypen wurde der Bruchteil der Zahl abgeschnitten. Für die Datentypen time, timestamp und interval, die eine Zeitkomponente enthalten, wurde der Bruchteil der Zeit abgeschnitten.

(Funktion gibt SQL_SUCCESS_WITH_INFO zurück.)
07006 Verletzung des eingeschränkten Datentyp-Attributs Der Datenwert einer Spalte im Resultset konnte nicht in den Datentyp konvertiert werden, der durch TargetType im Aufruf von SQLBindCol angegeben wurde.
07009 Ungültiger Deskriptorindex Das Argument Operation wurde SQL_REFRESH oder SQL_UPDATE, und eine Spalte wurde mit einer Spaltennummer gebunden, die größer als die Anzahl der Spalten im Resultset war.
21S02 Grad der abgeleiteten Tabelle stimmt nicht mit der Spaltenliste überein Das Argument Operation wurde SQL_UPDATE, und es waren keine Spalten aktualisierbar, da alle Spalten entweder ungebunden, schreibgeschützt waren oder der Wert in der gebundenen Länge bzw. des Indikatorpuffers SQL_COLUMN_IGNORE wurde.
22001 Zeichenfolgendaten, rechtes Abschneiden Das Argument Operation wurde SQL_UPDATE, und die Zuweisung eines Zeichen- oder Binärwerts zu einer Spalte führte zum Abschneiden von Zeichen (für Zeichen) oder ungleich NULL (für Binäre) Zeichen oder Bytes.
22003 Numerischer Wert außerhalb des Bereichs Das Argument Operation wurde SQL_UPDATE, und die Zuweisung eines numerischen Werts zu einer Spalte im Resultset führte dazu, dass der gesamte Teil (im Gegensatz zu Bruchteilen) der Zahl abgeschnitten wurde.

Das Argument Operation wurde SQL_REFRESH, und die Rückgabe des numerischen Werts für eine oder mehrere gebundene Spalten hätte zu einem Verlust signifikanter Ziffern geführt.
22007 Ungültiges datetime-Format Das Argument Operation wurde SQL_UPDATE, und die Zuweisung eines Datums- oder Zeitstempelwerts zu einer Spalte im Resultset führte dazu, dass das Feld Jahr, Monat oder Tag außerhalb des Bereichs lag.

Das Argument Operation wurde SQL_REFRESH, und die Rückgabe des Datums- oder Zeitstempelwerts für eine oder mehrere gebundene Spalten hätte dazu geführt, dass das Feld Jahr, Monat oder Tag außerhalb des Bereichs lag.
22008 Datum/Uhrzeit-Feldüberlauf Das Argument Operation wurde SQL_UPDATE, und die Leistung der Datetime-Arithmetik für Daten, die an eine Spalte im Resultset gesendet wurden, führte dazu, dass ein datetime-Feld (das Jahr,Monat, Tag, Stunde, Minute oder zweite Feld) des Ergebnisses außerhalb des zulässigen Wertebereichs für das Feld lag oder basierend auf den natürlichen Regeln des gregorianischen Kalenders für datetimes ungültig war.

Das Argument Operation wurde SQL_REFRESH, und die Leistung der Datetime-Arithmetik für daten, die aus dem Resultset abgerufen werden, führte dazu, dass das Ergebnis aufgrund der natürlichen Regeln des gregorianischen Kalenders für datetimes nicht zulässig ist oder ungültig war.
22015 Intervallfeldüberlauf Das Argument Operation wurde SQL_UPDATE, und die Zuweisung eines genauen numerischen oder Intervall-C-Typs zu einem Intervall-SQL-Datentyp führte zu einem Verlust signifikanter Ziffern.

Das Argument Operation wurde SQL_UPDATE; Beim Zuweisen zu einem SQL-Intervalltyp gab es keine Darstellung des Werts des Typs C im SQL-Typ interval.

Das Argument Operation wurde SQL_REFRESH, und die Zuweisung eines genauen numerischen oder Intervall-SQL-Typs zu einem Intervall-C-Typ führte zu einem Verlust signifikanter Ziffern im führenden Feld.

Das Argument Operation wurde SQL_ REFRESH; Beim Zuweisen zu einem Intervall-C-Typ gab es keine Darstellung des Werts des SQL-Typs im Intervalltyp C.
22018 Ungültiger Zeichenwert für die Umwandlungsspezifikation Das Argument Operation wurde SQL_REFRESH; Der C-Typ war ein exakter oder ungefährer numerischer Datentyp, ein datetime- oder ein Intervalldatentyp. Der SQL-Typ der Spalte war ein Zeichendatentyp; und der Wert in der Spalte war kein gültiges Literal des gebundenen C-Typs.

Das Argument Operation wurde SQL_UPDATE; Der SQL-Typ war ein exakter oder ungefährer numerischer Datentyp, ein datetime- oder ein Intervalldatentyp. der Typ C wurde SQL_C_CHAR; und der Wert in der Spalte war kein gültiges Literal des gebundenen SQL-Typs.
23000 Verletzung der Integritätseinschränkung Das Argument Operation wurde SQL_DELETE oder SQL_UPDATE, und eine Integritätseinschränkung wurde verletzt.
24.000 Ungültiger Cursorstatus StatementHandle befand sich in einem ausgeführten Zustand, aber kein Resultset war dem StatementHandle zugeordnet.

(DM) Ein Cursor war auf dem StatementHandle geöffnet, aber SQLFetch oder SQLFetchScroll wurde nicht aufgerufen.

Ein Cursor war auf dem StatementHandle geöffnet, und SQLFetchoder SQLFetchScroll wurde aufgerufen, aber der Cursor wurde vor dem Beginn des Resultsets oder nach dem Ende des Resultsets positioniert.

Das Argument Operation wurde SQL_DELETE, SQL_REFRESH oder SQL_UPDATE, und der Cursor wurde vor dem Beginn des Resultsets oder nach dem Ende des Resultsets positioniert.
40001 Serialisierungsfehler Die Transaktion wurde aufgrund eines Ressourcen-Deadlocks mit einer anderen Transaktion zurückgesetzt.
40003 Anweisungsabschluss unbekannt Bei der zugehörigen Verbindung ist während der Ausführung dieser Funktion ein Fehler aufgetreten, und der Status der Transaktion kann nicht bestimmt werden.
42000 Syntaxfehler oder Zugriffsverletzung Der Treiber konnte die Zeile nicht bei Bedarf sperren, um den im Argumentvorgang angeforderten Vorgang auszuführen.

Der Treiber konnte die Zeile nicht wie im Argument LockType angefordert sperren.
44000 WITH CHECK OPTION-Verstoß Das Argument Operation wurde SQL_UPDATE, und die Aktualisierung wurde für eine angezeigte Tabelle oder eine Tabelle ausgeführt, die von der angezeigten Tabelle abgeleitet wurde, die durch Angabe von WITH CHECK OPTION erstellt wurde, sodass eine oder mehrere zeilen, die von der Aktualisierung betroffen sind, nicht mehr in der angezeigten Tabelle vorhanden sind.
HY000 Allgemeiner Fehler Es ist ein Fehler aufgetreten, für den kein spezifischer SQLSTATE-Wert vorhanden war und für den kein implementierungsspezifischer SQLSTATE-Wert definiert wurde. Die von SQLGetDiagRec im *MessageText-Puffer zurückgegebene Fehlermeldung beschreibt den Fehler und seine Ursache.
HY001 Fehler bei der Speicherbelegung Der Treiber konnte keinen Arbeitsspeicher zuordnen, der für die Unterstützung der Ausführung oder Vervollständigung der Funktion erforderlich ist.
HY008 Vorgang abgebrochen Für statementHandle wurde die asynchrone Verarbeitung aktiviert. Die Funktion wurde aufgerufen, und bevor sie die Ausführung abgeschlossen hat, wurde SQLCancel oder SQLCancelHandle für das StatementHandle aufgerufen, und dann wurde die Funktion für die StatementHandle erneut aufgerufen.

Die Funktion wurde aufgerufen, und bevor sie die Ausführung abgeschlossen hat, wurde SQLCancel oder SQLCancelHandle auf der StatementHandle von einem anderen Thread in einer Multithreadanwendung aufgerufen.
HY010 Funktionssequenzfehler (DM) Eine asynchron ausgeführte Funktion wurde für das Verbindungshandle aufgerufen, das dem StatementHandle zugeordnet ist. Diese asynchrone Funktion wurde noch ausgeführt, als die SQLSetPos-Funktion aufgerufen wurde.

(DM) Die angegebene AnweisungHandle befand sich nicht in einem ausgeführten Zustand. Die Funktion wurde aufgerufen, ohne zuerst SQLExecDirect, SQLExecute oder eine Katalogfunktion aufzurufen.

(DM) Eine asynchron ausgeführte Funktion (nicht diese Funktion) wurde für das StatementHandle aufgerufen und wurde weiterhin ausgeführt, als diese Funktion aufgerufen wurde.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations oder SQLSetPos wurde für die StatementHandle aufgerufen und SQL_NEED_DATA zurückgegeben. Diese Funktion wurde aufgerufen, bevor Daten für alle Daten bei der Ausführung gesendet wurden.

(DM) Der Treiber war ein ODBC 2.x-Treiber , und SQLSetPos wurde für eine StatementHandle aufgerufen, nachdem SQLFetch aufgerufen wurde.
HY011 Attribut kann jetzt nicht festgelegt werden (DM) Der Treiber war ein ODBC 2.x-Treiber ; das Attribut SQL_ATTR_ROW_STATUS_PTR-Anweisung wurde festgelegt; dann wurde SQLSetPos aufgerufen, bevor SQLFetch, SQLFetchScroll oder SQLExtendedFetch aufgerufen wurde.
HY013 Fehler bei der Speicherverwaltung Der Funktionsaufruf konnte nicht verarbeitet werden, da auf die zugrunde liegenden Speicherobjekte nicht zugegriffen werden konnte, möglicherweise aufgrund von niedrigen Speicherbedingungen.
HY090 Ungültige Zeichenfolgen- oder Pufferlänge Das Argument Operation wurde SQL_UPDATE, ein Datenwert war ein NULL-Zeiger, und der Spaltenlängenwert war nicht 0, SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NULL_DATA oder kleiner als oder gleich SQL_LEN_DATA_AT_EXEC_OFFSET.

Das Argument Operation wurde SQL_UPDATE; ein Datenwert war kein NULL-Zeiger. der C-Datentyp wurde SQL_C_BINARY oder SQL_C_CHAR; und der Spaltenlängenwert war kleiner als 0, aber nicht gleich SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NTS oder SQL_NULL_DATA oder kleiner als oder gleich SQL_LEN_DATA_AT_EXEC_OFFSET.

Der Wert in einem Längen-/Indikatorpuffer wurde SQL_DATA_AT_EXEC; Der SQL-Typ war entweder SQL_LONGVARCHAR, SQL_LONGVARBINARY oder ein datenquellenspezifischer Langdatentyp; und der SQL_NEED_LONG_DATA_LEN Informationstyp in SQLGetInfo lautet "Y".
HY092 Ungültiger Attributbezeichner (DM) Der für das Argument Operation angegebene Wert war ungültig.

(DM) Der für das LockType-Argument angegebene Wert war ungültig.

Das Argument Operation wurde SQL_UPDATE oder SQL_DELETE, und das Attribut der SQL_ATTR_CONCURRENCY-Anweisung wurde SQL_ATTR_CONCUR_READ_ONLY.
HY107 Zeilenwert außerhalb des Bereichs Der für das Argument RowNumber angegebene Wert war größer als die Anzahl der Zeilen im Rowset.
HY109 Ungültige Cursorposition Der dem StatementHandle zugeordnete Cursor wurde als nur vorwärts definiert, sodass der Cursor nicht im Rowset positioniert werden konnte. Sehen Sie sich die Beschreibung des SQL_ATTR_CURSOR_TYPE-Attributs in SQLSetStmtAttr an.

Das Argument Operation wurde SQL_UPDATE, SQL_DELETE oder SQL_REFRESH, und die durch das RowNumber-Argument identifizierte Zeile wurde gelöscht oder nicht abgerufen.

(DM) Das RowNumber-Argument war 0, und das Argument Operation wurde SQL_POSITION.

SQLSetPos wurde aufgerufen, nachdem SQLBulkOperations aufgerufen wurde und bevor SQLFetchScroll oder SQLFetch aufgerufen wurde.
HY117 Die Verbindung wird aufgrund eines unbekannten Transaktionsstatus angehalten. Nur Trennen und schreibgeschützte Funktionen sind zulässig. (DM) Weitere Informationen zum Angehaltenen Zustand finden Sie unter SQLEndTran-Funktion.
HYC00 Optionale Funktion nicht implementiert Der Treiber oder die Datenquelle unterstützt den im Argument Operation oder im Argument LockType angeforderten Vorgang nicht.
HYT00 Timeout abgelaufen Der Abfragetimeoutzeitraum ist abgelaufen, bevor die Datenquelle das Resultset zurückgibt. Der Timeoutzeitraum wird über SQLSetStmtAttr mit einem Attribut von SQL_ATTR_QUERY_TIMEOUT festgelegt.
HYT01 Verbindungstimeout abgelaufen Der Zeitraum für das Verbindungstimeout ist abgelaufen, bevor die Datenquelle auf die Anforderung reagiert hat. Der Zeitraum für das Verbindungstimeout wird über SQLSetConnectAttr festgelegt, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Der Treiber unterstützt diese Funktion nicht. (DM) Der der StatementHandle zugeordnete Treiber unterstützt die Funktion nicht.
IM017 Die Abfrage ist im asynchronen Benachrichtigungsmodus deaktiviert. Wenn das Benachrichtigungsmodell verwendet wird, ist die Abfrage deaktiviert.
IM018 SQLCompleteAsync wurde nicht aufgerufen, um den vorherigen asynchronen Vorgang für dieses Handle abzuschließen. Wenn der vorherige Funktionsaufruf für das Handle SQL_STILL_EXECUTING zurückgibt und der Benachrichtigungsmodus aktiviert ist, muss SQLCompleteAsync für das Handle aufgerufen werden, um die Nachverarbeitung durchzuführen und den Vorgang abzuschließen.

Kommentare

Achtung

Informationen zur Anweisung, in der SQLSetPos aufgerufen werden kann, und zu den Aufgaben, die für die Kompatibilität mit ODBC 2.x-Anwendungen erforderlich sind, finden Sie unter Blockcursors, Scrollable Cursors und Abwärtskompatibilität.

RowNumber-Argument

Das RowNumber-Argument gibt die Anzahl der Zeile im Rowset an, für die der durch das Argument Operation angegebene Vorgang ausgeführt werden soll. Wenn RowNumber 0 ist, gilt der Vorgang für jede Zeile im Rowset. RowNumber muss ein Wert von 0 bis zur Anzahl der Zeilen im Rowset sein.

Hinweis

In der Sprache C sind Arrays 0-basiert, und das RowNumber-Argument ist 1-basiert. Um beispielsweise die fünfte Zeile des Rowsets zu aktualisieren, ändert eine Anwendung die Rowsetpuffer am Arrayindex 4, gibt jedoch eine RowNumber von 5 an.

Bei allen Vorgängen wird der Cursor in der durch RowNumber angegebenen Zeile positioniert. Die folgenden Vorgänge erfordern eine Cursorposition:

  • Positionierte Update- und Löschanweisungen.

  • Aufrufe von SQLGetData.

  • Aufrufe von SQLSetPos mit den Optionen SQL_DELETE, SQL_REFRESH und SQL_UPDATE.

Wenn beispielsweise RowNumber für einen Aufruf von SQLSetPos mit einem Vorgang von SQL_DELETE 2 ist, wird der Cursor in der zweiten Zeile des Rowsets positioniert, und diese Zeile wird gelöscht. Der Eintrag im Implementierungszeilenstatusarray (auf das SQL_ATTR_ROW_STATUS_PTR-Anweisungsattribut verweist) für die zweite Zeile wird in SQL_ROW_DELETED geändert.

Eine Anwendung kann beim Aufrufen von SQLSetPos eine Cursorposition angeben. Im Allgemeinen wird SQLSetPos mit dem SQL_POSITION- oder SQL_REFRESH-Vorgang aufgerufen, um den Cursor vor dem Ausführen einer positionierten Update- oder Delete-Anweisung oder dem Aufruf von SQLGetData zu positionieren.

Operation-Argument

Das Argument Operation unterstützt die folgenden Vorgänge. Um zu bestimmen, welche Optionen von einer Datenquelle unterstützt werden, ruft eine Anwendung SQLGetInfo mit dem Informationstyp SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 oder SQL_STATIC_CURSOR_ATTRIBUTES1 auf (abhängig vom Typ des Cursors).

Vorgang

Argument
Vorgang
SQL_POSITION Der Treiber positioniert den Cursor in der durch RowNumber angegebenen Zeile.

Der Inhalt des Zeilenstatusarrays, auf das das SQL_ATTR_ROW_OPERATION_PTR-Anweisungsattribut verweist, wird für den SQL_POSITION-Vorgang ignoriert.
SQL_REFRESH Der Treiber positioniert den Cursor in der durch RowNumber angegebenen Zeile und aktualisiert Daten in den Rowsetpuffern für diese Zeile. Weitere Informationen dazu, wie der Treiber Daten in den Rowsetpuffern zurückgibt, finden Sie in den Beschreibungen der zeilenweisen und spaltenweisen Bindung in SQLBindCol.

SQLSetPos mit einem Vorgang von SQL_REFRESH aktualisiert den Status und Inhalt der Zeilen im aktuell abgerufenen Rowset. Dies schließt das Aktualisieren der Lesezeichen ein. Da die Daten in den Puffern aktualisiert, aber nicht zurückgegeben werden, ist die Mitgliedschaft im Rowset behoben. Dies unterscheidet sich von der Aktualisierung durch einen Aufruf von SQLFetchScroll mit einer FetchOrientation von SQL_FETCH_RELATIVE und einer RowNumber gleich 0, die das Rowset aus dem Resultset zurückgibt, sodass hinzugefügte Daten angezeigt und gelöschte Daten entfernt werden können, wenn diese Vorgänge vom Treiber und dem Cursor unterstützt werden.

Eine erfolgreiche Aktualisierung mit SQLSetPos ändert den Zeilenstatus von SQL_ROW_DELETED nicht. Gelöschte Zeilen innerhalb des Rowsets werden bis zum nächsten Abruf weiterhin als gelöscht markiert. Die Zeilen werden beim nächsten Abruf ausgeblendet, wenn der Cursor das Packen unterstützt (in dem ein nachfolgendes SQLFetch oder SQLFetchScroll keine gelöschten Zeilen zurückgibt).

Hinzugefügte Zeilen werden nicht angezeigt, wenn eine Aktualisierung mit SQLSetPos ausgeführt wird. Dieses Verhalten unterscheidet sich von SQLFetchScroll mit einem FetchType von SQL_FETCH_RELATIVE und einer RowNumber gleich 0, wodurch auch das aktuelle Rowset aktualisiert wird, aber hinzugefügte Datensätze oder gelöschte Datensätze angezeigt werden, wenn diese Vorgänge vom Cursor unterstützt werden.

Eine erfolgreiche Aktualisierung mit SQLSetPos ändert den Zeilenstatus von SQL_ROW_ADDED in SQL_ROW_SUCCESS (wenn das Zeilenstatusarray vorhanden ist).

Bei einer erfolgreichen Aktualisierung mit SQLSetPos wird der Zeilenstatus SQL_ROW_UPDATED in den neuen Status der Zeile geändert (wenn das Zeilenstatusarray vorhanden ist).

Wenn in einem SQLSetPos-Vorgang für eine Zeile ein Fehler auftritt, wird der Zeilenstatus auf SQL_ROW_ERROR festgelegt (wenn das Zeilenstatusarray vorhanden ist).

Bei einem Cursor, der mit einem SQL_ATTR_CONCURRENCY-Anweisungsattribut von SQL_CONCUR_ROWVER oder SQL_CONCUR_VALUES geöffnet wird, kann eine Aktualisierung mit SQLSetPos die werte für die optimistische Parallelität aktualisieren, die von der Datenquelle verwendet werden, um zu erkennen, dass sich die Zeile geändert hat. In diesem Fall werden die Zeilenversionen oder Werte, die verwendet werden, um die Parallelität des Cursors sicherzustellen, aktualisiert, wenn die Rowsetpuffer vom Server aktualisiert werden. Dies tritt für jede Zeile auf, die aktualisiert wird.

Der Inhalt des Zeilenstatusarrays, auf das vom SQL_ATTR_ROW_OPERATION_PTR-Anweisungsattribut verwiesen wird, wird für den SQL_REFRESH-Vorgang ignoriert.
SQL_UPDATE Der Treiber positioniert den Cursor in der durch RowNumber angegebenen Zeile und aktualisiert die zugrunde liegende Datenzeile mit den Werten in den Rowsetpuffern (das Argument TargetValuePtr in SQLBindCol). Es ruft die Längen der Daten aus den Längen-/Indikatorpuffern ab (das argument StrLen_or_IndPtr in SQLBindCol). Wenn die Länge einer Spalte SQL_COLUMN_IGNORE ist, wird die Spalte nicht aktualisiert. Nach dem Aktualisieren der Zeile ändert der Treiber das entsprechende Element des Zeilenstatusarrays in SQL_ROW_UPDATED oder SQL_ROW_SUCCESS_WITH_INFO (sofern das Zeilenstatusarray vorhanden ist).

Es ist vom Treiber definiert, wie das Verhalten ist, wenn SQLSetPos mit dem Argument Operation SQL_UPDATE auf einem Cursor aufgerufen wird, der doppelte Spalten enthält. Der Treiber kann einen vom Treiber definierten SQLSTATE zurückgeben, die erste Spalte aktualisieren, die im Resultset angezeigt wird, oder ein anderes vom Treiber definiertes Verhalten ausführen.

Das Zeilenvorgangsarray, auf das das Attribut der SQL_ATTR_ROW_OPERATION_PTR-Anweisung verweist, kann verwendet werden, um anzugeben, dass eine Zeile im aktuellen Rowset während einer Massenaktualisierung ignoriert werden soll. Weitere Informationen finden Sie weiter unten in dieser Funktionsreferenz unter "Status- und Vorgangsarrays".
SQL_DELETE Der Treiber positioniert den Cursor in der durch RowNumber angegebenen Zeile und löscht die zugrunde liegende Datenzeile. Das entsprechende Element des Zeilenstatusarrays wird in SQL_ROW_DELETED geändert. Nachdem die Zeile gelöscht wurde, gilt Folgendes für die Zeile nicht: positionierte Update- und Delete-Anweisungen, Aufrufe von SQLGetData und Aufrufe von SQLSetPos , wobei Operation auf alles außer SQL_POSITION festgelegt ist. Bei Treibern, die das Packen unterstützen, wird die Zeile aus dem Cursor gelöscht, wenn neue Daten aus der Datenquelle abgerufen werden.

Ob die Zeile sichtbar bleibt, hängt vom Cursortyp ab. Beispielsweise sind gelöschte Zeilen für statische und keysetgesteuerte Cursor sichtbar, aber für dynamische Cursor nicht sichtbar.

Das Zeilenvorgangsarray, auf das vom SQL_ATTR_ROW_OPERATION_PTR-Anweisungsattribut verwiesen wird, kann verwendet werden, um anzugeben, dass eine Zeile im aktuellen Rowset während eines Massenlöschvorgangs ignoriert werden soll. Weitere Informationen finden Sie weiter unten in dieser Funktionsreferenz unter "Status- und Vorgangsarrays".

LockType-Argument

Das Argument LockType bietet Anwendungen eine Möglichkeit, die Parallelität zu steuern. In den meisten Fällen unterstützen Datenquellen, die Parallelitätsstufen und Transaktionen unterstützen, nur den SQL_LOCK_NO_CHANGE Wert des LockType-Arguments . Das Argument LockType wird in der Regel nur für die dateibasierte Unterstützung verwendet.

Das LockType-Argument gibt den Sperrstatus der Zeile an, nachdem SQLSetPos ausgeführt wurde. Wenn der Treiber die Zeile nicht sperren kann, um den angeforderten Vorgang auszuführen oder das LockType-Argument zu erfüllen, gibt er SQL_ERROR und SQLSTATE 42000 zurück (Syntaxfehler oder Zugriffsverletzung).

Obwohl das LockType-Argument für eine einzelne Anweisung angegeben wird, gewährt die Sperre allen Anweisungen für die Verbindung dieselben Berechtigungen. Insbesondere kann eine Sperre, die von einer Anweisung für eine Verbindung abgerufen wird, durch eine andere Anweisung für dieselbe Verbindung entsperrt werden.

Eine zeile, die über SQLSetPos gesperrt ist, bleibt gesperrt, bis die Anwendung SQLSetPos für die Zeile aufruft, deren LockType auf SQL_LOCK_UNLOCK festgelegt ist, oder bis die Anwendung SQLFreeHandle für die Anweisung oder SQLFreeStmt mit der option SQL_CLOSE aufruft. Für einen Treiber, der Transaktionen unterstützt, wird eine Zeile, die über SQLSetPos gesperrt ist, entsperrt, wenn die Anwendung SQLEndTran aufruft, um eine Transaktion für die Verbindung zu committen oder zurückzusetzen (wenn ein Cursor geschlossen wird, wenn eine Transaktion committet oder ein Rollback ausgeführt wird, wie durch die SQL_CURSOR_COMMIT_BEHAVIOR und SQL_CURSOR_ROLLBACK_BEHAVIOR Informationstypen angegeben, die von SQLGetInfo zurückgegeben werden).

Das LockType-Argument unterstützt die folgenden Sperrtypen. Um zu bestimmen, welche Sperren von einer Datenquelle unterstützt werden, ruft eine Anwendung SQLGetInfo mit dem Informationstyp SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 oder SQL_STATIC_CURSOR_ATTRIBUTES1 auf (abhängig vom Typ des Cursors).

LockType-Argument Sperrtyp
SQL_LOCK_NO_CHANGE Der Treiber oder die Datenquelle stellt sicher, dass sich die Zeile im gleichen gesperrten oder entsperrten Zustand wie vor dem Aufruf von SQLSetPos befindet. Mit diesem Wert von LockType können Datenquellen, die explizite Sperren auf Zeilenebene nicht unterstützen, alle Sperren verwenden, die für die aktuelle Parallelitäts- und Transaktionsisolationsstufen erforderlich sind.
SQL_LOCK_EXCLUSIVE Der Treiber oder die Datenquelle sperrt die Zeile ausschließlich. Eine Anweisung für eine andere Verbindung oder in einer anderen Anwendung kann nicht verwendet werden, um Sperren für die Zeile abzurufen.
SQL_LOCK_UNLOCK Der Treiber oder die Datenquelle entsperrt die Zeile.

Wenn ein Treiber SQL_LOCK_EXCLUSIVE, aber keine SQL_LOCK_UNLOCK unterstützt, bleibt eine gesperrte Zeile gesperrt, bis einer der im vorherigen Absatz beschriebenen Funktionsaufrufe auftritt.

Wenn ein Treiber SQL_LOCK_EXCLUSIVE, aber keine SQL_LOCK_UNLOCK unterstützt, bleibt eine gesperrte Zeile gesperrt, bis die Anwendung SQLFreeHandle für die -Anweisung oder SQLFreeStmt mit der option SQL_CLOSE aufruft. Wenn der Treiber Transaktionen unterstützt und den Cursor beim Commit oder Rollback der Transaktion schließt, ruft die Anwendung SQLEndTran auf.

Für die Aktualisierungs- und Löschvorgänge in SQLSetPos verwendet die Anwendung das LockType-Argument wie folgt:

  • Um sicherzustellen, dass sich eine Zeile nach dem Abrufen nicht ändert, ruft eine Anwendung SQLSetPos auf, wobei Operation auf SQL_REFRESH und LockType auf SQL_LOCK_EXCLUSIVE festgelegt ist.

  • Wenn die Anwendung LockType auf SQL_LOCK_NO_CHANGE festlegt, garantiert der Treiber, dass ein Update- oder Löschvorgang nur dann erfolgreich ist, wenn die Anwendung SQL_CONCUR_LOCK für das Attribut der SQL_ATTR_CONCURRENCY-Anweisung angegeben hat.

  • Wenn die Anwendung SQL_CONCUR_ROWVER oder SQL_CONCUR_VALUES für das attribut der SQL_ATTR_CONCURRENCY-Anweisung angibt, vergleicht der Treiber Zeilenversionen oder -werte und lehnt den Vorgang ab, wenn sich die Zeile seit dem Abrufen der Zeile geändert hat.

  • Wenn die Anwendung SQL_CONCUR_READ_ONLY für das SQL_ATTR_CONCURRENCY-Anweisungsattribut angibt, lehnt der Treiber alle Aktualisierungs- oder Löschvorgänge ab.

Weitere Informationen zum SQL_ATTR_CONCURRENCY-Anweisungsattribut finden Sie unter SQLSetStmtAttr.

Status- und Vorgangsarrays

Die folgenden Status- und Vorgangsarrays werden beim Aufrufen von SQLSetPos verwendet:

  • Das Zeilenstatusarray (auf das SQL_DESC_ARRAY_STATUS_PTR Feld im IRD und das Attribut der SQL_ATTR_ROW_STATUS_ARRAY-Anweisung verweist) enthält Statuswerte für jede Datenzeile im Rowset. Der Treiber legt die Statuswerte in diesem Array nach einem Aufruf von SQLFetch, SQLFetchScroll, SQLBulkOperations oder SQLSetPos fest. Auf dieses Array zeigt das SQL_ATTR_ROW_STATUS_PTR-Anweisungsattribut.

  • Das Zeilenvorgangsarray (auf das SQL_DESC_ARRAY_STATUS_PTR Feld in der ARD und das Attribut der SQL_ATTR_ROW_OPERATION_ARRAY-Anweisung verweist) enthält einen Wert für jede Zeile im Rowset, der angibt, ob ein Aufruf von SQLSetPos für einen Massenvorgang ignoriert oder ausgeführt wird. Jedes Element im Array ist entweder auf SQL_ROW_PROCEED (Standard) oder auf SQL_ROW_IGNORE festgelegt. Auf dieses Array zeigt das Attribut der SQL_ATTR_ROW_OPERATION_PTR-Anweisung.

Die Anzahl der Elemente in den Status- und Vorgangsarrays muss der Anzahl der Zeilen im Rowset entsprechen (wie durch das Attribut der SQL_ATTR_ROW_ARRAY_SIZE-Anweisung definiert).

Informationen zum Zeilenstatusarray finden Sie unter SQLFetch. Informationen zum Zeilenvorgangsarray finden Sie weiter unten in diesem Abschnitt unter "Ignorieren einer Zeile in einem Massenvorgang".

Verwenden von SQLSetPos

Bevor eine Anwendung SQLSetPos aufruft, muss sie die folgende Abfolge von Schritten ausführen:

  1. Wenn die Anwendung SQLSetPos aufruft, wobei Operation auf SQL_UPDATE festgelegt ist, rufen Sie SQLBindCol (oder SQLSetDescRec) für jede Spalte auf, um den Datentyp anzugeben und Puffer für die Daten und länge der Spalte zu binden.

  2. Wenn die Anwendung SQLSetPos aufruft, wobei Operation auf SQL_DELETE oder SQL_UPDATE festgelegt ist, rufen Sie SQLColAttribute auf, um sicherzustellen, dass die zu löschenden oder zu aktualisierenden Spalten aktualisierbar sind.

  3. Rufen Sie SQLExecDirect, SQLExecute oder eine Katalogfunktion auf, um ein Resultset zu erstellen.

  4. Rufen Sie SQLFetch oder SQLFetchScroll auf, um die Daten abzurufen.

Weitere Informationen zur Verwendung von SQLSetPos finden Sie unter Aktualisieren von Daten mit SQLSetPos.

Löschen von Daten mithilfe von SQLSetPos

Zum Löschen von Daten mit SQLSetPos ruft eine Anwendung SQLSetPos auf, wobei RowNumber auf die Nummer der zu löschenden Zeile und Operation auf SQL_DELETE festgelegt ist.

Nachdem die Daten gelöscht wurden, ändert der Treiber den Wert im Array der Implementierungszeilenstatus für die entsprechende Zeile in SQL_ROW_DELETED (oder SQL_ROW_ERROR).

Aktualisieren von Daten mithilfe von SQLSetPos

Eine Anwendung kann den Wert für eine Spalte entweder im gebundenen Datenpuffer oder mit einem oder mehreren Aufrufen von SQLPutData übergeben. Spalten, deren Daten mit SQLPutData übergeben werden, werden als Daten bei Ausführungsspalten bezeichnet. Diese werden häufig zum Senden von Daten für SQL_LONGVARBINARY und SQL_LONGVARCHAR Spalten verwendet und können mit anderen Spalten gemischt werden.

So aktualisieren Sie Daten mit SQLSetPos, einer Anwendung:

  1. Platziert Werte in den Daten- und Längen-/Indikatorpuffern, die an SQLBindCol gebunden sind:

    • Bei normalen Spalten platziert die Anwendung den neuen Spaltenwert im Puffer *TargetValuePtr und die Länge dieses Werts im Puffer *StrLen_or_IndPtr . Wenn die Zeile nicht aktualisiert werden soll, platziert die Anwendung SQL_ROW_IGNORE im Zeilenvorgangsarray dieser Zeile.

    • Für Daten bei Ausführungsspalten platziert die Anwendung einen von der Anwendung definierten Wert, z. B. die Spaltennummer, im *TargetValuePtr-Puffer . Der Wert kann später verwendet werden, um die Spalte zu identifizieren.

      Die Anwendung platziert das Ergebnis des Makros SQL_LEN_DATA_AT_EXEC(länge) im Puffer *StrLen_or_IndPtr . Wenn der SQL-Datentyp der Spalte SQL_LONGVARBINARY, SQL_LONGVARCHAR oder ein langer datenquellenspezifischer Datentyp ist und der Treiber "Y" für den SQL_NEED_LONG_DATA_LEN Informationstyp in SQLGetInfo zurückgibt, entspricht length der Anzahl der Für den Parameter zu sendenden Bytes. Andernfalls muss es sich um einen nicht negativen Wert handelt und wird ignoriert.

  2. Ruft SQLSetPos auf, wobei das Argument Operation auf SQL_UPDATE festgelegt ist, um die Datenzeile zu aktualisieren.

    • Wenn keine Daten bei der Ausführung vorhanden sind, ist der Prozess abgeschlossen.

    • Wenn Daten bei Ausführungsspalten vorhanden sind, gibt die Funktion SQL_NEED_DATA zurück und fährt mit Schritt 3 fort.

  3. Ruft SQLParamData auf, um die Adresse des *TargetValuePtr-Puffers für die erste zu verarbeitende Datenausführungsspalte abzurufen. SQLParamData gibt SQL_NEED_DATA zurück. Die Anwendung ruft den von der Anwendung definierten Wert aus dem *TargetValuePtr-Puffer ab.

    Hinweis

    Obwohl Data-at-Execution-Parameter ähnlich wie Data-at-Execution-Spalten sind, unterscheidet sich der von SQLParamData zurückgegebene Wert für jede Spalte.

    Hinweis

    Data-at-Execution-Parameter sind Parameter in einer SQL-Anweisung, für die Daten mit SQLPutData gesendet werden, wenn die Anweisung mit SQLExecDirect oder SQLExecute ausgeführt wird. Sie werden mit SQLBindParameter oder durch Festlegen von Deskriptoren mit SQLSetDescRec gebunden. Der von SQLParamData zurückgegebene Wert ist ein 32-Bit-Wert, der im ParameterValuePtr-Argument an SQLBindParameter übergeben wird.

    Hinweis

    Daten bei Ausführungsspalten sind Spalten in einem Rowset, für die Daten mit SQLPutData gesendet werden, wenn eine Zeile mit SQLSetPos aktualisiert wird. Sie sind mit SQLBindCol gebunden. Der von SQLParamData zurückgegebene Wert ist die Adresse der Zeile im *TargetValuePtr-Puffer , der verarbeitet wird.

  4. Ruft SQLPutData einmal oder mehrmals auf, um Daten für die Spalte zu senden. Es sind mehrere Aufrufe erforderlich, wenn nicht alle Datenwerte im * TargetValuePtr-Puffer zurückgegeben werden können, der in SQLPutData angegeben ist. Mehrere Aufrufe von SQLPutData für dieselbe Spalte sind nur zulässig, wenn Zeichen-C-Daten an eine Spalte mit einem zeichen-, binär- oder datenquellenspezifischen Datentyp gesendet werden oder wenn binäre C-Daten an eine Spalte mit einem zeichen-, binär- oder datenquellenspezifischen Datentyp gesendet werden.

  5. Ruft SQLParamData erneut auf, um zu signalisieren, dass alle Daten für die Spalte gesendet wurden.

    • Wenn mehr Data-at-Execution-Spalten vorhanden sind, gibt SQLParamData SQL_NEED_DATA und die Adresse des TargetValuePtr-Puffers für die nächste zu verarbeitende Data-at-Execution-Spalte zurück. Die Anwendung wiederholt die Schritte 4 und 5.

    • Wenn keine Data-at-Execution-Spalten mehr vorhanden sind, ist der Prozess abgeschlossen. Wenn die Anweisung erfolgreich ausgeführt wurde, gibt SQLParamData SQL_SUCCESS oder SQL_SUCCESS_WITH_INFO zurück. Wenn bei der Ausführung ein Fehler aufgetreten ist, wird SQL_ERROR zurückgegeben. An diesem Punkt kann SQLParamData einen beliebigen SQLSTATE-Wert zurückgeben, der von SQLSetPos zurückgegeben werden kann.

Wenn Daten aktualisiert wurden, ändert der Treiber den Wert im Array für den Status der Implementierungszeile für die entsprechende Zeile in SQL_ROW_UPDATED.

Wenn der Vorgang abgebrochen wird oder ein Fehler in SQLParamData oder SQLPutData auftritt, kann die Anwendung nur SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions, SQLParamData oder SQLPutData für die Anweisung oder die Verbindung aufrufen, nachdem SQLSetPos SQL_NEED_DATA zurückgibt und vor dem Senden von Daten für alle Daten bei ausführungsbasierten Spalten nur SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions, SQLParamData oder SQLPutData für die Anweisung oder die Verbindung aufrufen. Wenn eine andere Funktion für die -Anweisung oder die der -Anweisung zugeordnete Verbindung aufgerufen wird, gibt die Funktion SQL_ERROR und SQLSTATE HY010 (Funktionssequenzfehler) zurück.

Wenn die Anwendung SQLCancel aufruft, während der Treiber weiterhin Daten für Daten bei der Ausführung benötigt, bricht der Treiber den Vorgang ab. Die Anwendung kann dann SQLSetPos erneut aufrufen. Canceling wirkt sich nicht auf den Cursorzustand oder die aktuelle Cursorposition aus.

Wenn die SELECT-Liste der Abfragespezifikation, die dem Cursor zugeordnet ist, mehr als einen Verweis auf dieselbe Spalte enthält, ist der Treiber unabhängig davon, ob ein Fehler generiert wird oder der Treiber die duplizierten Verweise ignoriert und die angeforderten Vorgänge ausführt, treiberdefiniert.

Ausführen von Massenvorgängen

Wenn das RowNumber-Argument 0 ist, führt der Treiber den im Argument Operation angegebenen Vorgang für jede Zeile im Rowset aus, deren Feld im Zeilenvorgangsarray mit SQL_ATTR_ROW_OPERATION_PTR Anweisung den Wert SQL_ROW_PROCEED hat. Dies ist ein gültiger Wert des RowNumber-Arguments für ein Operation-Argument von SQL_DELETE, SQL_REFRESH oder SQL_UPDATE, aber nicht SQL_POSITION. SQLSetPos mit einem Vorgang von SQL_POSITION und einer RowNumber gleich 0 gibt SQLSTATE HY109 (ungültige Cursorposition) zurück.

Wenn ein Fehler auftritt, der sich auf das gesamte Rowset bezieht, z. B. SQLSTATE HYT00 (Timeout abgelaufen), gibt der Treiber SQL_ERROR und die entsprechende SQLSTATE zurück. Der Inhalt der Rowsetpuffer ist nicht definiert, und die Cursorposition bleibt unverändert.

Wenn ein Fehler auftritt, der sich auf eine einzelne Zeile bezieht, hat der Treiber folgendes:

  • Legt das Element für die Zeile im Zeilenstatusarray, auf das das Attribut der SQL_ATTR_ROW_STATUS_PTR-Anweisung verweist, auf SQL_ROW_ERROR fest.

  • Stellt ein oder mehrere zusätzliche SQLSTATEs für den Fehler in der Fehlerwarteschlange bereit und legt das Feld SQL_DIAG_ROW_NUMBER in der Diagnosedatenstruktur fest.

Wenn der Treiber den Vorgang für die verbleibenden Zeilen im Rowset abgeschlossen hat, gibt er nach der Verarbeitung des Fehlers oder der Warnung SQL_SUCCESS_WITH_INFO zurück. Daher enthält die Fehlerwarteschlange für jede Zeile, die einen Fehler zurückgegeben hat, null oder mehr zusätzliche SQLSTATEs. Wenn der Treiber den Vorgang beendet, nachdem er den Fehler oder die Warnung verarbeitet hat, gibt er SQL_ERROR zurück.

Wenn der Treiber Warnungen zurückgibt, z. B. SQLSTATE 01004 (Daten abgeschnitten), gibt er Warnungen zurück, die für das gesamte Rowset oder für unbekannte Zeilen im Rowset gelten, bevor er die Fehlerinformationen zurückgibt, die für bestimmte Zeilen gelten. Es werden Warnungen für bestimmte Zeilen zusammen mit anderen Fehlerinformationen zu diesen Zeilen zurückgegeben.

Wenn RowNumber gleich 0 und Operation SQL_UPDATE, SQL_REFRESH oder SQL_DELETE ist, wird die Anzahl der Zeilen, für die SQLSetPos ausgeführt wird, vom Attribut der SQL_ATTR_ROWS_FETCHED_PTR-Anweisung auf die Anzahl der Zeilen verwiesen, auf die SQLSetPos ausgeführt wird.

Wenn RowNumber gleich 0 und Operation SQL_DELETE, SQL_REFRESH oder SQL_UPDATE ist, entspricht die aktuelle Zeile nach dem Vorgang der aktuellen Zeile vor dem Vorgang.

Ignorieren einer Zeile in einem Massenvorgang

Das Zeilenvorgangsarray kann verwendet werden, um anzugeben, dass eine Zeile im aktuellen Rowset während eines Massenvorgangs mit SQLSetPos ignoriert werden soll. Um den Treiber anzuweisen, während eines Massenvorgangs eine oder mehrere Zeilen zu ignorieren, sollte eine Anwendung die folgenden Schritte ausführen:

  1. Rufen Sie SQLSetStmtAttr auf, um das SQL_ATTR_ROW_OPERATION_PTR-Anweisungsattribut so festzulegen, dass es auf ein Array von SQLUSMALLINTs verweist. Dieses Feld kann auch durch Aufrufen von SQLSetDescField festgelegt werden, um das SQL_DESC_ARRAY_STATUS_PTR Headerfeld der ARD festzulegen, was erfordert, dass eine Anwendung das Deskriptorhandle abruft.

  2. Legen Sie jedes Element des Zeilenvorgangsarrays auf einen von zwei Werten fest:

    • SQL_ROW_IGNORE, um anzugeben, dass die Zeile für den Massenvorgang ausgeschlossen ist.

    • SQL_ROW_PROCEED, um anzugeben, dass die Zeile im Massenvorgang enthalten ist. (Dies ist der Standardwert.)

  3. Rufen Sie SQLSetPos auf, um den Massenvorgang auszuführen.

Die folgenden Regeln gelten für das Zeilenvorgangsarray:

  • SQL_ROW_IGNORE und SQL_ROW_PROCEED wirken sich nur auf Massenvorgänge mit SQLSetPos mit einem Vorgang von SQL_DELETE oder SQL_UPDATE aus. Sie wirken sich nicht auf Aufrufe von SQLSetPos mit einem Vorgang von SQL_REFRESH oder SQL_POSITION aus.

  • Der Zeiger ist standardmäßig auf NULL festgelegt.

  • Wenn der Zeiger NULL ist, werden alle Zeilen aktualisiert, als ob alle Elemente auf SQL_ROW_PROCEED festgelegt wären.

  • Das Festlegen eines Elements auf SQL_ROW_PROCEED garantiert nicht, dass der Vorgang für diese bestimmte Zeile ausgeführt wird. Wenn beispielsweise eine bestimmte Zeile im Rowset den Status SQL_ROW_ERROR hat, kann der Treiber diese Zeile möglicherweise nicht aktualisieren, unabhängig davon, ob die angegebene Anwendung SQL_ROW_PROCEED. Eine Anwendung muss immer das Zeilenstatusarray überprüfen, um festzustellen, ob der Vorgang erfolgreich war.

  • SQL_ROW_PROCEED wird in der Headerdatei als 0 definiert. Eine Anwendung kann das Zeilenvorgangsarray auf 0 initialisieren, um alle Zeilen zu verarbeiten.

  • Wenn die Elementnummer "n" im Zeilenvorgangsarray auf SQL_ROW_IGNORE festgelegt ist und SQLSetPos aufgerufen wird, um einen Massenaktualisierungs- oder Löschvorgang auszuführen, bleibt die n. Zeile im Rowset nach dem Aufruf von SQLSetPos unverändert.

  • Eine Anwendung sollte automatisch eine schreibgeschützte Spalte auf SQL_ROW_IGNORE festlegen.

Ignorieren einer Spalte in einem Massenvorgang

Um unnötige Verarbeitungsdiagnosen zu vermeiden, die durch versuchte Aktualisierungen einer oder mehrerer schreibgeschützter Spalten generiert werden, kann eine Anwendung den Wert im Puffer der gebundenen Länge/des Indikators auf SQL_COLUMN_IGNORE festlegen. Weitere Informationen finden Sie unter SQLBindCol.

Codebeispiel

Im folgenden Beispiel ermöglicht eine Anwendung einem Benutzer, die TABELLE ORDERS zu durchsuchen und den Bestellstatus zu aktualisieren. Der Cursor ist keysetgesteuert mit einer Rowsetgröße von 20 und verwendet eine optimistische Parallelitätssteuerung, die Zeilenversionen vergleicht. Nachdem jedes Rowset abgerufen wurde, gibt die Anwendung es aus und ermöglicht es dem Benutzer, den Status einer Bestellung auszuwählen und zu aktualisieren. Die Anwendung verwendet SQLSetPos , um den Cursor in der ausgewählten Zeile zu positionieren und eine positionierte Aktualisierung der Zeile durchzuführen. (Fehlerbehandlung wird aus Gründen der Übersichtlichkeit weggelassen.)

#define ROWS 20  
#define STATUS_LEN 6  
  
SQLCHAR        szStatus[ROWS][STATUS_LEN], szReply[3];  
SQLINTEGER     cbStatus[ROWS], cbOrderID;  
SQLUSMALLINT   rgfRowStatus[ROWS];  
SQLUINTEGER    sOrderID, crow = ROWS, irow;  
SQLHSTMT       hstmtS, hstmtU;  
  
SQLSetStmtAttr(hstmtS, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0);  
SQLSetStmtAttr(hstmtS, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_KEYSET_DRIVEN, 0);  
SQLSetStmtAttr(hstmtS, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0);  
SQLSetStmtAttr(hstmtS, SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) rgfRowStatus, 0);  
SQLSetCursorName(hstmtS, "C1", SQL_NTS);  
SQLExecDirect(hstmtS, "SELECT ORDERID, STATUS FROM ORDERS ", SQL_NTS);  
  
SQLBindCol(hstmtS, 1, SQL_C_ULONG, &sOrderID, 0, &cbOrderID);  
SQLBindCol(hstmtS, 2, SQL_C_CHAR, szStatus, STATUS_LEN, &cbStatus);  
  
while ((retcode == SQLFetchScroll(hstmtS, SQL_FETCH_NEXT, 0)) != SQL_ERROR) {  
   if (retcode == SQL_NO_DATA_FOUND)  
      break;  
   for (irow = 0; irow < crow; irow++) {  
      if (rgfRowStatus[irow] != SQL_ROW_DELETED)  
         printf("%2d %5d %*s\n", irow+1, sOrderID, NAME_LEN-1, szStatus[irow]);  
   }  
   while (TRUE) {  
      printf("\nRow number to update?");  
      gets_s(szReply, 3);  
      irow = atoi(szReply);  
      if (irow > 0 && irow <= crow) {  
         printf("\nNew status?");  
         gets_s(szStatus[irow-1], (ROWS * STATUS_LEN));  
         SQLSetPos(hstmtS, irow, SQL_POSITION, SQL_LOCK_NO_CHANGE);  
         SQLPrepare(hstmtU,  
          "UPDATE ORDERS SET STATUS=? WHERE CURRENT OF C1", SQL_NTS);  
         SQLBindParameter(hstmtU, 1, SQL_PARAM_INPUT,  
            SQL_C_CHAR, SQL_CHAR,  
            STATUS_LEN, 0, szStatus[irow], 0, NULL);  
         SQLExecute(hstmtU);  
      } else if (irow == 0) {  
         break;  
      }  
   }  
}  

Weitere Beispiele finden Sie unter Positionierte Update- und Delete-Anweisungen und Aktualisieren von Zeilen im Rowset mit SQLSetPos.

Informationen über Finden Sie unter
Binden eines Puffers an eine Spalte in einem Resultset SQLBindCol-Funktion
Ausführen von Massenvorgängen, die sich nicht auf die Position des Blockcursors beziehen SQLBulkOperations-Funktion
Abbrechen der Anweisungsverarbeitung SQLCancel-Funktion
Abrufen eines Datenblocks oder Scrollen durch ein Resultset SQLFetchScroll-Funktion
Abrufen eines einzelnen Felds eines Deskriptors SQLGetDescField-Funktion
Abrufen mehrerer Felder eines Deskriptors SQLGetDescRec-Funktion
Festlegen eines einzelnen Felds eines Deskriptors SQLSetDescField-Funktion
Festlegen mehrerer Felder eines Deskriptors SQLSetDescRec-Funktion
Festlegen eines Anweisungsattributs SQLSetStmtAttr-Funktion

Weitere Informationen

ODBC-API-Referenz
ODBC-Headerdateien