Teilen über


SQLSetPos-Funktion

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

Zusammenfassung
SQLSetPos legt die Cursorposition in einem Rowset fest und ermöglicht einer Anwendung das Aktualisieren von Daten im Rowset oder das Aktualisieren oder Löschen von Daten im Resultset.

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 SQL_ADD aus Gründen der Abwärtskompatibilität 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 nach dem Ausführen des im Argument Operation angegebenen Vorgangs gesperrt wird.

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.

Diagnostik

Wenn SQLSetPos SQL_ERROR oder SQL_SUCCESS_WITH_INFO zurückgibt, kann ein zugeordneter SQLSTATE-Wert durch Aufrufen von SQLGetDiagRec mit einem HandleType von SQL_HANDLE_STMT und einem Handle of StatementHandle abgerufen werden. In der folgenden Tabelle sind die SQLSTATE-Werte aufgeführt, die häufig von SQLSetPos zurückgegeben werden, und jede wird 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 (mit Ausnahme von 01xxx SQLSTATEs) zurückgeben können, wird SQL_SUCCESS_WITH_INFO zurückgegeben, wenn ein Fehler für einen oder mehrere, jedoch nicht alle Zeilen eines Mehrzeilenvorgangs auftritt, und SQL_ERROR zurückgegeben wird, wenn ein Fehler bei einem Einzelzeilenvorgang auftritt.

SQLSTATE Error Beschreibung
01000 Allgemeiner Warnhinweis 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 mehr als eine Zeile gelöscht oder aktualisiert. (Weitere Informationen zu Updates für mehr als eine Zeile finden Sie in der Beschreibung des SQL_ATTR_SIMULATE_CURSOR Attribut 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 Zeichenfolgendaten rechts abgeschnitten 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 nicht leeren Zeichen- oder Nicht-NULL-Binärdaten.
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 einen oder mehrere, jedoch nicht alle Zeilen eines Multirow-Vorgangs auftritt, und SQL_ERROR zurückgegeben wird, wenn bei einem Einzelzeilenvorgang ein Fehler auftritt.)

(Dieser SQLSTATE-Wert wird nur zurückgegeben, wenn SQLSetPos wird nach SQLExtendedFetch aufgerufen, wenn der Treiber ein ODBC 2.x-Treiber ist und die Cursorbibliothek nicht verwendet wird.)
01S07 Bruchabkürzung Das Argument "Operation " wurde SQL_REFRESH, der Datentyp des Anwendungspuffers wurde nicht SQL_C_CHAR oder SQL_C_BINARY, und die an Anwendungspuffer zurückgegebenen Daten für eine oder mehrere Spalten wurden abgeschnitten. Bei numerischen Datentypen wurde der Bruchteil der Zahl abgeschnitten. Für Zeit-, Zeitstempel- und Intervalldatentypen, 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 durch TargetType angegebenen Datentyp im Aufruf von SQLBindCol konvertiert werden.
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 ist.
21S02 Der Grad der abgeleiteten Tabelle stimmt nicht mit der Spaltenliste überein. Das Argument "Operation " war SQL_UPDATE, und es konnten keine Spalten aktualisiert werden, da alle Spalten entweder ungebunden, schreibgeschützt oder der Wert im gebundenen Längen-/Indikatorpuffer SQL_COLUMN_IGNORE wurde.
22001 Zeichenfolgendaten, rechter Abschneiden Das Argument Operation wurde SQL_UPDATE, und die Zuordnung eines Zeichens oder binärwerts zu einer Spalte führte zum Abschneiden von nicht leeren Zeichen (für Zeichen) oder nicht null (für Binäre) Zeichen oder Bytes.
22003 Numerischer Wert außerhalb des Bereichs Das Argument "Operation " wurde SQL_UPDATE, und die Zuordnung eines numerischen Werts zu einer Spalte im Resultset hat dazu geführt, dass der gesamte Teil (im Gegensatz zu Bruchzahlen) der Zahl abgeschnitten wird.

Das Argument "Operation " wurde SQL_REFRESH, und das Zurückgeben 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 Zuordnung eines Datums- oder Zeitstempelwerts zu einer Spalte im Resultset hat dazu geführt, dass das Feld "Jahr", "Monat" oder "Tag" nicht im Bereich liegt.

The argument Operation was SQL_REFRESH, and returning the date or timestamp value for one or more bound columns would have caused the year, month, or day field to out of range.
22008 Überlauf des Datums-/Uhrzeitfelds Das Argument "Operation " wurde SQL_UPDATE, und die Leistung der Datetime-Arithmetik für Daten, die an eine Spalte im Resultset gesendet werden, führte zu einem Datumstimefeld (Jahr, Monat, Tag, Stunde, Minute oder zweites Feld) des Ergebnisses, das außerhalb des zulässigen Wertebereichs für das Feld liegt oder aufgrund der natürlichen Regeln des gregorianischen Kalenders für Datumsangaben ungültig ist.

Das Argument "Operation " wurde SQL_REFRESH, und die Leistung der Datums-/Uhrzeitarithmetik für Daten, die aus dem Resultset abgerufen werden, führte zu einem Datumstimefeld (Jahr, Monat, Tag, Stunde, Minute oder zweites Feld) des Ergebnisses, das außerhalb des zulässigen Wertebereichs für das Feld liegt oder aufgrund der natürlichen Regeln des gregorianischen Kalenders für Datumsangaben ungültig ist.
22015 Intervallfeldüberlauf Das Argument "Operation " wurde SQL_UPDATE, und die Zuordnung eines exakten numerischen oder Intervall-C-Typs zu einem SQL-Intervalldatentyp verursachte einen Verlust signifikanter Ziffern.

Das Argument "Operation " wurde SQL_UPDATE; beim Zuweisen eines SQL-Intervalltyps gab es keine Darstellung des Werts des C-Typs im SQL-Intervalltyp.

Das Argument "Operation " wurde SQL_REFRESH, und das Zuweisen von einem genauen numerischen oder Intervall-SQL-Typ zu einem Intervall C-Typ verursachte einen Verlust signifikanter Ziffern im führenden Feld.

Das Argument Operation war SQL_ REFRESH; beim Zuweisen eines Intervalls C-Typs gab es keine Darstellung des Werts des SQL-Typs im Intervall C-Typ.
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 Datums- oder 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 C-Typ war SQL_C_CHAR; und der Wert in der Spalte war kein gültiges Literal des gebundenen SQL-Typs.
23000 Integritätseinschränkungsverletzung Das Argument "Operation " wurde SQL_DELETE oder SQL_UPDATE, und eine Integritätseinschränkung wurde verletzt.
24000 Ungültiger Cursorstatus The StatementHandle was in an executed state, but no result set was associated with the StatementHandle.

(DM) Ein Cursor wurde im StatementHandle geöffnet, aber SQLFetch oder SQLFetchScroll wurden nicht aufgerufen.

Ein Cursor war für " StatementHandle" geöffnet, und SQLFetch Oder SQLFetchScroll wurde aufgerufen, der Cursor wurde jedoch vor dem Start des Resultsets oder nach dem Ende des Resultsets positioniert.

Das Argument "Operation " war SQL_DELETE, SQL_REFRESH oder SQL_UPDATE, und der Cursor wurde vor dem Start 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 Abschluss der Anweisung unbekannt Fehler bei der zugehörigen Verbindung während der Ausführung dieser Funktion, und der Status der Transaktion kann nicht bestimmt werden.
42000 Syntaxfehler oder Zugriffsverletzung Der Treiber konnte die Zeile bei Bedarf nicht sperren, um den im Argument "Operation" 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 mindestens eine zeile, die von der Aktualisierung betroffen ist, nicht mehr in der angezeigten Tabelle vorhanden ist.
HY000 Allgemeiner Fehler Es ist ein Fehler aufgetreten, für den kein spezifischer SQLSTATE-Wert vorhanden war und für den keine implementierungsspezifische SQLSTATE definiert wurde. Die von SQLGetDiagRec im *MessageText-Puffer zurückgegebene Fehlermeldung beschreibt den Fehler und dessen Ursache.
HY001 Speicherzuweisungsfehler Der Treiber konnte speicher nicht zuordnen, der erforderlich ist, um die Ausführung oder den Abschluss der Funktion zu unterstützen.
HY008 Vorgang abgebrochen Die asynchrone Verarbeitung wurde für " StatementHandle" 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 erneut für "StatementHandle" aufgerufen.

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

(DM) Das angegebene StatementHandle war 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) wurde für das StatementHandle aufgerufen und wurde noch ausgeführt, als diese Funktion aufgerufen wurde.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations oder SQLSetPos wurde für " StatementHandle " aufgerufen und SQL_NEED_DATA zurückgegeben. Diese Funktion wurde aufgerufen, bevor Daten für alle Daten bei ausführungsparametern oder -spalten gesendet wurden.

(DM) Der Treiber war ein ODBC 2.x-Treiber, und SQLSetPos wurde nach dem Aufrufen von SQLFetch für ein StatementHandle aufgerufen.
HY011 Attribut kann jetzt nicht festgelegt werden (DM) Der Treiber war ein ODBC 2.x-Treiber; das attribut der SQL_ATTR_ROW_STATUS_PTR-Anweisung wurde festgelegt; dann wurde SQLSetPos aufgerufen, bevor SQLFetch, SQLFetchScroll oder SQLExtendedFetch aufgerufen wurde.
HY013 Speicherverwaltungsfehler Der Funktionsaufruf konnte nicht verarbeitet werden, da auf die zugrunde liegenden Speicherobjekte nicht zugegriffen werden konnte, möglicherweise aufgrund geringer Arbeitsspeicherbedingungen.
HY090 Ungültige Zeichenfolgen- oder Pufferlänge Das Argument Operation war SQL_UPDATE, ein Datenwert war ein Nullzeiger, 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 war SQL_UPDATE; ein Datenwert war kein Nullzeiger; der Datentyp C 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 langer datenquellenspezifischer Datentyp; und der SQL_NEED_LONG_DATA_LEN Informationstyp in SQLGetInfo lautete "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 "vorwärts" definiert, sodass der Cursor nicht innerhalb des Rowsets positioniert werden konnte. Weitere Informationen finden Sie in der Beschreibung für das attribut SQL_ATTR_CURSOR_TYPE in SQLSetStmtAttr.

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

(DM) Das Argument RowNumber 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 des unbekannten Transaktionsstatus angehalten. Es sind nur Trenn- und schreibgeschützte Funktionen zulässig. (DM) Weitere Informationen zum angehaltenen Zustand finden Sie unter SQLEndTran Function.
HYC00 Optionales Feature wurde nicht implementiert Der Treiber oder die Datenquelle unterstützt den im Argument "Operation" oder im Argument "LockType" angeforderten Vorgang nicht.
HYT00 Timeout überschritten 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 geantwortet hat. Der Verbindungstimeoutzeitraum wird über SQLSetConnectAttr SQL_ATTR_CONNECTION_TIMEOUT festgelegt.
IM001 Dieser Treiber unterstützt diese Funktion nicht. (DM) Der dem StatementHandle zugeordnete Treiber unterstützt die Funktion nicht.
IM017 Die Abrufung ist im asynchronen Benachrichtigungsmodus deaktiviert. Immer wenn das Benachrichtigungsmodell verwendet wird, ist die Abrufung 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 Nachbearbeitung durchzuführen und den Vorgang abzuschließen.

Kommentare

Achtung

Informationen zu den Anweisungen besagt, dass SQLSetPos aufgerufen werden kann und was sie zur Kompatibilität mit ODBC 2.x-Anwendungen ausführen muss, finden Sie unter "Blockcursors", "Scrollbare Cursor" und "Abwärtskompatibilität".

RowNumber-Argument

Das Argument RowNumber gibt die Nummer 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 Argument RowNumber 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.

Alle Vorgänge positionieren den Cursor auf der Zeile, die durch RowNumber angegeben wird. Für die folgenden Vorgänge ist eine Cursorposition erforderlich:

  • Positionierte Aktualisierungs- und Löschanweisungen.

  • Aufrufe an SQLGetData.

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

Wenn "RowNumber" beispielsweise 2 für einen Aufruf von SQLSetPos mit einem Vorgang von SQL_DELETE ist, wird der Cursor in der zweiten Zeile des Rowsets positioniert und diese Zeile gelöscht. Der Eintrag im Statusarray der Implementierungszeile (auf das attribut der SQL_ATTR_ROW_STATUS_PTR-Anweisung 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 ruft es SQLSetPos mit dem SQL_POSITION- oder SQL_REFRESH-Vorgang auf, um den Cursor zu positionieren, bevor eine positionierte Aktualisierungs- oder Löschanweisung ausgeführt oder SQLGetData aufgerufen wird.

Operation-Argument

Das Argument Operation unterstützt die folgenden Vorgänge. Um zu ermitteln, welche Optionen von einer Datenquelle unterstützt werden, ruft eine Anwendung SQLGetInfo mit dem SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 oder SQL_STATIC_CURSOR_ATTRIBUTES1 Informationstyp (je nach Cursortyp) auf.

Vorgang

Argument
Vorgang
SQL_POSITION Der Treiber positioniert den Cursor an der Zeile, die durch RowNumber angegeben wird.

Der Inhalt des Zeilenstatusarrays, auf das das Attribut der SQL_ATTR_ROW_OPERATION_PTR-Anweisung 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 Zeilen- und Spaltenbindung in SQLBindCol.

SQLSetPos mit einem Vorgang von SQL_REFRESH aktualisiert den Status und Den Inhalt der Zeilen innerhalb des aktuellen abgerufenen Rowsets. Dazu gehört das Aktualisieren der Lesezeichen. Da die Daten in den Puffern aktualisiert, aber nicht zurückgerufen werden, ist die Mitgliedschaft im Rowset behoben. Dies unterscheidet sich von der Aktualisierung, die von einem Aufruf von SQLFetchScroll mit einer FetchOrientation von SQL_FETCH_RELATIVE und einer RowNumber gleich 0 ausgeführt wird, wodurch das Rowset aus dem Resultset zurückgesetzt wird, 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 keinen Zeilenstatus von SQL_ROW_DELETED. 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-Element 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, die auch das aktuelle Rowset aktualisiert, aber hinzugefügte Datensätze anzeigt oder gelöschte Datensätze enthält, wenn diese Vorgänge vom Cursor unterstützt werden.

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

Eine erfolgreiche Aktualisierung mit SQLSetPos ändert einen Zeilenstatus von SQL_ROW_UPDATED in den neuen Status der Zeile (wenn das Zeilenstatusarray vorhanden ist).

Wenn in einem SQLSetPos-Vorgang in einer 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 wurde, aktualisiert eine Aktualisierung mit SQLSetPos möglicherweise die optimistischen Parallelitätswerte, die von der Datenquelle verwendet werden, um zu erkennen, dass sich die Zeile geändert hat. Wenn dies der Fall ist, werden die Zeilenversionen oder Werte, die verwendet werden, um sicherzustellen, dass die Cursorkoncurrität aktualisiert werden, wenn die Rowsetpuffer vom Server aktualisiert werden. Dies geschieht für jede Zeile, die aktualisiert wird.

Der Inhalt des Zeilenstatusarrays, auf das das attribut der SQL_ATTR_ROW_OPERATION_PTR-Anweisung verweist, wird für den SQL_REFRESH-Vorgang ignoriert.
SQL_UPDATE Der Treiber positioniert den Cursor in der zeile, die durch RowNumber angegeben wird, und aktualisiert die zugrunde liegende Datenzeile mit den Werten in den Rowsetpuffern (das TargetValuePtr-Argument in SQLBindCol). Sie ruft die Längen der Daten aus den Längen-/Indikatorpuffern ab (das StrLen_or_IndPtr Argument 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 (wenn das Zeilenstatusarray vorhanden ist).

Es ist treiberdefiniert, was das Verhalten ist, wenn SQLSetPos mit einem Argument "Operation " von SQL_UPDATE für einen 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 treiberdefiniertes 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 zeile, die durch RowNumber angegeben wird, und löscht die zugrunde liegende Datenzeile. Es ändert das entsprechende Element des Zeilenstatusarrays in SQL_ROW_DELETED. Nachdem die Zeile gelöscht wurde, sind die folgenden ungültig für die Zeile: positionierte Aktualisierungs- und Löschanweisungen, Aufrufe von SQLGetData und Aufrufe von SQLSetPos mit Operation auf alles außer SQL_POSITION festgelegt. Bei Treibern, die das Packen unterstützen, wird die Zeile vom 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 unsichtbar.

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 eines Massenlöschvorgangs ignoriert werden soll. Weitere Informationen finden Sie weiter unten in dieser Funktionsreferenz unter "Status- und Vorgangsarrays".

LockType-Argument

Das LockType-Argument bietet eine Möglichkeit, um die Parallelität von Anwendungen zu steuern. In den meisten Fällen unterstützen Datenquellen, die Parallelitätsebenen und Transaktionen unterstützen, nur den SQL_LOCK_NO_CHANGE Wert des LockType-Arguments . Das LockType-Argument wird in der Regel nur für 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, wird SQL_ERROR und SQLSTATE 42000 (Syntaxfehler oder Zugriffsverletzung) zurückgegeben.

Obwohl das LockType-Argument für eine einzelne Anweisung angegeben ist, bezieht sich die Sperre auf dieselben Berechtigungen auf alle Anweisungen für die Verbindung. Insbesondere kann eine Sperre, die von einer Anweisung für eine Verbindung erworben 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, wobei 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 übernehmen oder zurückzusetzen (wenn ein Cursor geschlossen wird, wenn eine Transaktion zugesichert oder zurückgesetzt wird, wie durch die SQL_CURSOR_COMMIT_BEHAVIOR und SQL_CURSOR_ROLLBACK_BEHAVIOR von SQLGetInfo zurückgegebenen Informationstypen).

Das LockType-Argument unterstützt die folgenden Sperrtypen. Um zu ermitteln, welche Sperren von einer Datenquelle unterstützt werden, ruft eine Anwendung SQLGetInfo mit dem SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 oder SQL_STATIC_CURSOR_ATTRIBUTES1 Informationstyp (je nach Cursortyp) auf.

LockType-Argument Sperrtyp
SQL_LOCK_NO_CHANGE Der Treiber oder die Datenquelle stellt sicher, dass sich die Zeile im gleichen gesperrten oder entsperrten Zustand befindet wie vor dem Aufrufen von SQLSetPos . Dieser Wert von LockType ermöglicht Datenquellen, die keine explizite Sperrung auf Zeilenebene unterstützen, um die von den aktuellen Parallelitäts- und Transaktionsisolationsstufen erforderliche Sperrung zu verwenden.
SQL_LOCK_EXCLUSIVE Der Treiber oder die Datenquelle sperrt die Zeile exklusiv. Eine Anweisung für eine andere Verbindung oder in einer anderen Anwendung kann nicht zum Abrufen von Sperren in der Zeile verwendet werden.
SQL_LOCK_UNLOCK Der Treiber oder die Datenquelle entsperrt die Zeile.

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

Wenn ein Treiber SQL_LOCK_EXCLUSIVE unterstützt, 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 mit Operation auf SQL_REFRESH und LockType auf SQL_LOCK_EXCLUSIVE festgelegt.

  • Wenn die Anwendung LockType auf SQL_LOCK_NO_CHANGE festlegt, garantiert der Treiber, dass ein Aktualisierungs- oder Löschvorgang nur erfolgreich ausgeführt wird, wenn die Anwendung SQL_CONCUR_LOCK für das Attribut 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 Attribut der SQL_ATTR_CONCURRENCY-Anweisung angibt, lehnt der Treiber aktualisierungs- oder Löschvorgänge ab.

Weitere Informationen zum attribut der SQL_ATTR_CONCURRENCY-Anweisung finden Sie unter SQLSetStmtAttr.

Status- und Vorgangsarrays

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

  • Das Zeilenstatusarray (wie durch das feld SQL_DESC_ARRAY_STATUS_PTR in der IRD und das Attribut der SQL_ATTR_ROW_STATUS_ARRAY-Anweisung) 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. Dieses Array wird durch das Attribut SQL_ATTR_ROW_STATUS_PTR-Anweisung verwiesen.

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

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 Schrittfolge ausführen:

  1. Wenn die Anwendung SQLSetPos mit operation set to SQL_UPDATE aufruft, 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 mit Operation set auf SQL_DELETE oder SQL_UPDATE aufruft, rufen Sie SQLColAttribute auf, um sicherzustellen, dass die zu löschenden oder aktualisierten 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 mit RowNumber auf die Nummer der zu löschenden Zeile und den Vorgangssatz auf SQL_DELETE.

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

Aktualisieren von Daten mit 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 *TargetValuePtr-Puffer und die Länge dieses Werts im *StrLen_or_IndPtr Puffer. Wenn die Zeile nicht aktualisiert werden soll, platziert die Anwendung SQL_ROW_IGNORE im Element dieser Zeile des Zeilenvorgangsarrays.

    • Bei Daten bei Ausführungsspalten platziert die Anwendung einen anwendungsdefinierten 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 *StrLen_or_IndPtr puffer. 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, ist die Länge die Anzahl der Bytes, die für den Parameter gesendet werden sollen. Andernfalls muss es sich um einen nicht negativen Wert handeln und ignoriert werden.

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

    • Wenn keine Daten bei ausführungsspalten vorhanden sind, ist der Vorgang 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 Datenspalte abzurufen. SQLParamData gibt SQL_NEED_DATA zurück. Die Anwendung ruft den anwendungsdefinierte Wert aus dem *TargetValuePtr-Puffer ab.

    Hinweis

    Obwohl datenbasierte Ausführungsparameter mit Daten bei ausführungsspalten vergleichbar sind, unterscheidet sich der von SQLParamData zurückgegebene Wert für jeden.

    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 sind 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 auf, um Daten für die Spalte zu senden. Es sind mehrere Aufrufe erforderlich, wenn nicht alle Datenwerte im in SQLPutData angegebenen *TargetValuePtr-Puffer zurückgegeben werden können. Mehrere Aufrufe von SQLPutData für dieselbe Spalte sind nur zulässig, wenn Zeichen C-Daten an eine Spalte mit einem Zeichen, einer Binärdatei oder einem datenquellenspezifischen Datentyp oder beim Senden von binären C-Daten an eine Spalte mit einem Zeichen gesendet werden, binär oder datenquellenspezifischer Datentyp.

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

    • Wenn weitere Daten bei ausführungsspalten vorhanden sind, gibt SQLParamData SQL_NEED_DATA und die Adresse des TargetValuePtr-Puffers für die nächste daten-at-execution-Spalte zurück, die verarbeitet werden soll. Die Anwendung wiederholt die Schritte 4 und 5.

    • Wenn keine Datenspalten mehr vorhanden sind, ist der Vorgang abgeschlossen. Wenn die Anweisung erfolgreich ausgeführt wurde, gibt SQLParamData SQL_SUCCESS oder SQL_SUCCESS_WITH_INFO zurück. Wenn die Ausführung fehlgeschlagen ist, wird SQL_ERROR zurückgegeben. Zu diesem Zeitpunkt kann SQLParamData jeden SQLSTATE-Wert zurückgeben, der von SQLSetPos zurückgegeben werden kann.

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

Wenn der Vorgang abgebrochen wird oder ein Fehler in SQLParamData oder SQLPutData auftritt, nachdem SQLSetPos SQL_NEED_DATA zurückgibt und bevor Daten für alle Daten bei ausführungsspalten gesendet werden, kann die Anwendung nur SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions, SQLParamData oder SQLPutData für die Anweisung oder die Verbindung aufrufen, die der Anweisung zugeordnet ist. Wenn sie eine andere Funktion für die Anweisung oder die verbindung der Anweisung aufruft, 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 ausführungsspalten benötigt, bricht der Treiber den Vorgang ab. Die Anwendung kann dann SQLSetPos erneut aufrufen. Das Abbrechen wirkt sich nicht auf den Cursorzustand oder die aktuelle Cursorposition aus.

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

Ausführen von Massenvorgängen

Wenn das Argument RowNumber 0 ist, führt der Treiber den im Argument "Operation" angegebenen Vorgang für jede Zeile im Rowset aus, die einen Wert von SQL_ROW_PROCEED in seinem Feld im Zeilenvorgangsarray aufweist, auf das durch SQL_ATTR_ROW_OPERATION_PTR -Anweisungsattribut verwiesen wird. Dies ist ein gültiger Wert des RowNumber-Arguments für ein Argument "Operation " 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 den entsprechenden SQLSTATE zurück. Der Inhalt der Rowsetpuffer ist nicht definiert, und die Cursorposition ist unverändert.

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

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

  • Stellt einen oder mehrere zusätzliche SQLSTATEs für den Fehler in der Fehlerwarteschlange hinzu und legt das feld SQL_DIAG_ROW_NUMBER in der Diagnosedatenstruktur fest.

Nachdem der Fehler oder die Warnung verarbeitet wurde, wird SQL_SUCCESS_WITH_INFO zurückgegeben, wenn der Treiber den Vorgang für die verbleibenden Zeilen im Rowset abgeschlossen hat. 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, wird SQL_ERROR zurückgegeben.

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

Wenn "RowNumber " gleich 0 ist und "Operation " SQL_UPDATE, SQL_REFRESH oder SQL_DELETE ist, wird die Anzahl der Zeilen , auf denen SQLSetPos ausgeführt wird, durch das attribut SQL_ATTR_ROWS_FETCHED_PTR-Anweisung verwiesen.

Wenn "RowNumber " gleich 0 ist 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. Damit der Treiber während eines Massenvorgangs eine oder mehrere Zeilen ignoriert, sollte eine Anwendung die folgenden Schritte ausführen:

  1. Rufen Sie SQLSetStmtAttr auf, um das attribut der SQL_ATTR_ROW_OPERATION_PTR-Anweisung auf ein Array von SQLUSMALLINTs zu verweisen. Dieses Feld kann auch durch Aufrufen von SQLSetDescField festgelegt werden, um das SQL_DESC_ARRAY_STATUS_PTR Kopfzeilenfeld der ARD festzulegen, was erfordert, dass eine Anwendung das Deskriptorhandle abruft.

  2. Legen Sie jedes Element des Zeilenvorgangsarray 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 wurden.

  • Das Festlegen eines Elements auf SQL_ROW_PROCEED garantiert nicht, dass der Vorgang in dieser bestimmten 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 Anwendung SQL_ROW_PROCEED angegeben hat. 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 nth 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 an einer oder mehreren schreibgeschützten Spalten generiert werden, kann eine Anwendung den Wert im gebundenen Längen-/Indikatorpuffer auf SQL_COLUMN_IGNORE festlegen. Weitere Informationen finden Sie unter SQLBindCol.

Codebeispiel

Im folgenden Beispiel ermöglicht eine Anwendung es einem Benutzer, die Tabelle ORDERS zu durchsuchen und den Bestellstatus zu aktualisieren. Der Cursor ist keysetgesteuert mit einer Rowsetgröße von 20 und verwendet optimistische Parallelitätssteuerelemente, die Zeilenversionen vergleichen. Nachdem jedes Rowset abgerufen wurde, druckt die Anwendung sie 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 auszufü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 Positioned Update- und Delete-Anweisungen und Aktualisieren von Zeilen im Rowset mit SQLSetPos.

Weitere Informationen zu Siehe
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 Verarbeitung von Anweisungen 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