SQLSetPos, funkcja

Zgodność
Wprowadzona wersja: Zgodność ze standardami ODBC 1.0: ODBC

Podsumowanie
SQLSetPos ustawia pozycję kursora w wierszu i pozwala aplikacji odświeżać dane w tym zbiorze lub aktualizować lub usuwać dane z tego zbioru.

Syntax

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

Arguments

StatementHandle
[Dane wejściowe] Uchwyt instrukcji.

Nr wiersza
[Input] Pozycja wiersza w zbiorze wierszy, na którym wykonać operację określoną argumentem Operation . Jeśli argument RowNumber ma wartość 0, operacja ma zastosowanie do każdego wiersza w zestawie wierszy.

Dodatkowe informacje można znaleźć w sekcji "Komentarze."

Operation
[Input] Operacja do wykonania:

SQL_POSITION SQL_REFRESH SQL_UPDATE SQL_DELETE

Uwaga / Notatka

Wartość SQL_ADD dla argumentu Operacja została wycofana dla ODBC 3.x. Sterowniki ODBC 3.x będą musiały wspierać SQL_ADD ze względu na kompatybilność wsteczną. Ta funkcjonalność została zastąpiona wywołaniem SQLBulkOperations z Operacją SQL_ADD. Gdy aplikacja ODBC 3.x pracuje z sterownikiem ODBC 2.x , Driver Manager mapuje wywołanie do SQLBulkOperations z operacją SQL_ADD do SQLSetPos z operacją SQL_ADD.

Więcej informacji znajdziesz w sekcji "Komentarze."

LockType
[Input] Określa, jak zablokować wiersz po wykonaniu operacji określonej w argumentze Operation .

SQL_LOCK_NO_CHANGE SQL_LOCK_EXCLUSIVE SQL_LOCK_UNLOCK

Więcej informacji znajdziesz w sekcji "Komentarze."

Zwroty

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

Diagnostyka

Gdy SQLSetPos zwraca SQL_ERROR lub SQL_SUCCESS_WITH_INFO, powiązaną wartość SQLSTATE można uzyskać, wywołując SQLGetDiagRec z HandleType SQL_HANDLE_STMT oraz HandleStatementHandle. Poniższa tabela przedstawia wartości SQLSTATE najczęściej zwracane przez SQLSetPos i wyjaśnia każdą z nich w kontekście tej funkcji; notacja "(DM)" poprzedza opisy stanów SQL zwracanych przez Menedżera Sterowników. Kod zwracany skojarzony z każdą wartością SQLSTATE jest SQL_ERROR, chyba że określono inaczej.

Dla wszystkich stanów SQL, które mogą zwracać SQL_SUCCESS_WITH_INFO lub SQL_ERROR (z wyjątkiem 01xxx SQLSTATE), SQL_SUCCESS_WITH_INFO zwracany, jeśli błąd wystąpi na jednym lub więcej, ale nie we wszystkich wierszach operacji wielowierszowej, a SQL_ERROR zwracany, jeśli błąd wystąpi w operacji pojedynczej wierszowej.

SQLSTATE Error Opis
01000 Ostrzeżenie ogólne Komunikat informacyjny specyficzny dla sterownika. (Funkcja zwraca SQL_SUCCESS_WITH_INFO).
01001 Konflikt operacji kursora Argument Operacja brzmiał SQL_DELETE lub SQL_UPDATE, a żadne wiersze ani więcej niż jeden wiersz nie zostały usunięte ani zaktualizowane. (Więcej informacji o aktualizacjach więcej niż jednego wiersza można znaleźć w opisie atrybutu SQL_ATTR_SIMULATE_CURSOR w SQLSetStmtAttr.) (Funkcja zwraca SQL_SUCCESS_WITH_INFO.)

Argument dotyczący Operacji był SQL_DELETE lub SQL_UPDATE, a operacja zakończyła się niepowodzeniem z powodu optymistycznego współbieżności. (Funkcja zwraca SQL_SUCCESS_WITH_INFO).
01004 Obcięcie prawej skracki danych ciągu Argument Operacja był SQL_REFRESH, a dane ciągowe lub binarne zwracane dla kolumny lub kolumn o typie danych SQL_C_CHAR lub SQL_C_BINARY skutkowały obcięciem niepustych znaków lub danych binarnych nie-NULL.
01S01 Błąd w wierszu Argument RowNumber wynosił 0, a błąd wystąpił w jednym lub więcej wierszach podczas wykonywania operacji określonej argumentem Operation .

(SQL_SUCCESS_WITH_INFO zwraca się, gdy błąd wystąpi na jednym lub więcej, ale nie we wszystkich wierszach operacji wielowierszowej, a SQL_ERROR zwracany, gdy błąd wystąpi w operacji jednowierszowej.)

(Ten SQLSTATE zwracany jest tylko wtedy, gdy SQLSetPos jest wywoływany po SQLExtendedFetch, jeśli sterownik jest sterownikiem ODBC 2.x i biblioteka kursorów nie jest używana.)
01S07 Obcięcie ułamkowe Argument Operation był SQL_REFRESH, typ danych bufora aplikacji nie był SQL_C_CHAR ani SQL_C_BINARY, a dane zwracane do buforów aplikacji dla jednej lub więcej kolumn były obcinane. Dla typów danych numerycznych część ułamkowa była obcięta. Dla typów danych czasowych, znaczników czasowych i interwałowych zawierających skład czasowy, część ułamkowa tego czasu była obcięta.

(Funkcja zwraca SQL_SUCCESS_WITH_INFO).
07006 Naruszenie atrybutu typu danych z ograniczeniami Wartość danych kolumny w zbiorze wyników nie mogła zostać przekonwertowana na typ danych określony przez TargetType w wywołaniu SQLBindCol.
07009 Nieprawidłowy indeks deskryptorów Argument Operacja to SQL_REFRESH lub SQL_UPDATE, a kolumna była owiązywana z numerem kolumny większym niż liczba kolumn w zbiorze wyników.
21S02 Stopień tabeli pochodnej nie jest zgodny z listą kolumn Operacja argumentowa była SQL_UPDATE, a żadne kolumny nie były aktualizowane, ponieważ wszystkie kolumny były albo niepowiązane, tylko do odczytu, albo wartość w buforze długości bound/indicator była SQL_COLUMN_IGNORE.
22001 Dane ciągowe, obcinanie z prawej Argument Operation był SQL_UPDATE, a przypisanie znaku lub wartości binarnej do kolumny skutkowało obcięciem znaków lub bajtów niepustych (dla znaków) lub nie-null (dla binarnych).
22003 Wartość liczbowa poza zakresem Argument Operation był SQL_UPDATE, a przypisanie wartości liczbowej kolumnie w zbiorze wyników powodowało obcięcie całej (a nie ułamkowej) części liczby.

Argument Operacja był SQL_REFRESH, a zwrot wartości liczbowej dla jednej lub więcej powiązanych kolumn spowodowałby utratę znaczących cyfr.
22007 Nieprawidłowy format daty/godziny Argument Operacja był SQL_UPDATE, a przypisanie wartości daty lub znacznika czasu do kolumny w zestawie wyników powodowało, że pole rok, miesiąc lub dzień było poza zakresem.

Argument Operacja był SQL_REFRESH, a zwracanie wartości daty lub znacznika czasu dla jednej lub więcej kolumn wiązanych powodowałoby wykraczanie pola roku, miesiąca lub dnia poza zakres.
22008 Przepełnienie pola daty/czasu Argument Operacji był SQL_UPDATE, a wykonanie arytmetyki datowej na danych przesyłanych do kolumny w zbiorze wyników skutkowało tym, że pole daty (rok, miesiąc, dzień, godzina, minuta lub drugie pole) wyniku, wykraczało poza dopuszczalny zakres wartości dla pola lub było nieważne ze względu na naturalne reguły kalendarza gregoriańskiego dotyczące dat.

Argument operacji był SQL_REFRESH, a wykonanie arytmetyki datowej na podstawie danych pobieranych z zestawu wyników skutkowało tym, że pole daty (rok, miesiąc, dzień, godzina, minuta lub drugie pole) wyniku, wykraczało poza dopuszczalny zakres wartości dla pola lub było nieważne ze względu na naturalne reguły kalendarza gregoriańskiego dotyczące dat.
22015 Przepełnienie pola interwału Argument Operation był SQL_UPDATE, a przypisanie dokładnego numerycznego lub interwałowego typu C do typu SQL interwałowego powodowało utratę istotnych cyfr.

Argument dotyczący Operacji był SQL_UPDATE; przy przypisywaniu typu SQL interwałowego nie było reprezentacji wartości typu C w typie SQL interwału.

Argument Operacja był SQL_REFRESH, a przypisanie z dokładnego numerycznego lub interwałowego typu SQL do typu przedziałowego C powodowało utratę istotnych cyfr w polu wiodącym.

Argument dotyczący operacji brzmiał SQL_ REFRESH; przy przypisywaniu do typu przedziału C nie było reprezentacji wartości typu SQL w typie przedziału C.
22018 Nieprawidłowa wartość znaku dla specyfikacji rzutu Argument dotyczący Operacji był SQL_REFRESH; typ C był dokładnym lub przybliżonym numerycznym typem danych, datą lub przedziałem; typ SQL kolumny był typem danych znaków; a wartość w kolumnie nie była prawidłowym literalem typu C z wiązaniem.

Argumentem Operacja była SQL_UPDATE; typ SQL był dokładnym lub przybliżonym numerem, datą lub typem danych interwałowych; typ C był SQL_C_CHAR; a wartość w kolumnie nie była prawidłowym literalem powiązanego typu SQL.
23000 Naruszenie ograniczeń integralności Argument Operacja była SQL_DELETE lub SQL_UPDATE, a naruszono ograniczenie integralności.
24000 Nieprawidłowy stan kursora CommandHandle był w stanie wykonania, ale żaden zestaw wyników nie był powiązany z StatementHandle.

(DM) Kursor był otwarty na StatementHandle, ale SQLFetch ani SQLFetchScroll nie zostały wywołane.

Na CommandHandle był otwarty kursor, a wywołano SQLFetch lub SQLFetchScroll , ale kursor był umieszczony przed początkiem zbioru wyników lub po jego zakończeniu.

Argument Operation to SQL_DELETE, SQL_REFRESH lub SQL_UPDATE, a kursor znajdował się przed początkiem zbioru wyników lub po jego końcu.
40001 Niepowodzenie serializacji Transakcja została wycofana z powodu zakleszczenia zasobu z inną transakcją.
40003 Ukończenie instrukcji nieznane Skojarzone połączenie nie powiodło się podczas wykonywania tej funkcji, a nie można określić stanu transakcji.
42000 Błąd składniowy lub naruszenie dostępu Sterownik nie był w stanie zablokować wiersza zgodnie z koniecznością wykonania operacji żądanej w argumentze Operation.

Kierowca nie był w stanie zablokować tego rzędu, jak żądano w argumentze LockType.
44000 Z NARUSZENIEM OPCJI SPRAWDZANIA Argument Operation był SQL_UPDATE, a aktualizacja była wykonywana na wyświetlonej tabeli lub na tabeli pochodzącej z tej tabeli, która została utworzona przez podanie Z OPCJĄ CHECK, tak że jeden lub więcej wierszy dotkniętych aktualizacją nie będzie już obecne w tej tabeli.
HY000 Błąd ogólny Wystąpił błąd, dla którego nie było określonego stanu SQLSTATE i dla którego nie zdefiniowano parametru SQLSTATE specyficznego dla implementacji. Komunikat o błędzie zwrócony przez element SQLGetDiagRec w buforze *MessageText opisuje błąd i jego przyczynę.
HY001 Błąd alokacji pamięci Sterownik nie może przydzielić pamięci wymaganej do obsługi wykonywania lub ukończenia funkcji.
HY008 Operacja anulowana Przetwarzanie asynchroniczne zostało włączone dla instrukcji StatementHandle. Funkcja została wywołana, a przed zakończeniem wykonania wywołano SQLCancel lub SQLCancelHandle na CommandHandle, a następnie ponownie wywołało ją na CommandHandle.

Wywołano funkcję , a przed zakończeniem wykonywania wywołano funkcję SQLCancel lub SQLCancelHandle na instrukcjiHandle z innego wątku w aplikacji wielowątku.
HY010 Błąd sekwencji funkcji (DM) Asynchronicznie wykonywana funkcja została wywołana dla dojścia połączenia skojarzonego z instrukcją StatementHandle. Ta asynchroniczna funkcja działała nadal, gdy wywoływano funkcję SQLSetPos.

(DM) Określony CommandHandle nie był w stanie wykonania. Funkcja była wywoływana bez wcześniejszego wywołania SQLExecDirect, SQLExecute lub funkcji katalogowej.

(DM) Asynchronicznie wykonująca funkcję (a nie tę) została wywołana dla instrukcji StatementHandle i nadal była wykonywana, gdy ta funkcja została wywołana.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations lub SQLSetPos został wywołany dla instrukcjiHandle i zwrócił SQL_NEED_DATA. Ta funkcja została wywołana przed wysłaniem danych dla wszystkich parametrów wykonywania danych lub kolumn.

(DM) Sterownik był sterownikiem ODBC 2.x , a SQLSetPos był wywoływany do StatementHandle po wywołaniu SQLFetch .
HY011 Atrybut nie może być teraz ustawiony (DM) Sterownik był sterownikiem ODBC 2.x ; atrybut SQL_ATTR_ROW_STATUS_PTR Statement został ustawiony; następnie SQLSetPos był wywoływany przed wywołaniem SQLFetch, SQLFetchScroll lub SQLExtendedFetch .
HY013 Błąd zarządzania pamięcią Nie można przetworzyć wywołania funkcji, ponieważ nie można uzyskać dostępu do bazowych obiektów pamięci, prawdopodobnie z powodu niskich warunków pamięci.
HY090 Nieprawidłowa długość ciągu lub buforu Argument Operacja był SQL_UPDATE, wartość danych była wskaźnikiem zerowym, a wartość długości kolumny nie była 0, SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NULL_DATA ani nie mniejsza ani równa SQL_LEN_DATA_AT_EXEC_OFFSET.

Argument dotyczący Operacji był SQL_UPDATE; wartość danych nie była wskaźnikiem zerowym; typ danych C to SQL_C_BINARY lub SQL_C_CHAR; a wartość długości kolumny była mniejsza niż 0, ale nie równa SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NTS lub SQL_NULL_DATA, ani mniejsza lub równa SQL_LEN_DATA_AT_EXEC_OFFSET.

Wartość w buforze długości/wskaźnika wynosiła SQL_DATA_AT_EXEC; typ SQL to albo SQL_LONGVARCHAR, SQL_LONGVARBINARY, albo długi typ danych specyficzny dla źródła danych; a SQL_NEED_LONG_DATA_LEN typ informacji w SQLGetInfo to "Y".
HY092 Nieprawidłowy identyfikator atrybutu (DM) Wartość podana dla argumentu Operation była nieprawidłowa.

(DM) Wartość podana dla argumentu LockType była nieprawidłowa.

Argument Operacja to SQL_UPDATE lub SQL_DELETE, a atrybut SQL_ATTR_CONCURRENCY to SQL_ATTR_CONCUR_READ_ONLY.
HY107 Wartość wiersza poza zakresem Wartość określona dla argumentu RowNumber była większa niż liczba wierszy w zestawie wierszy.
HY109 Nieprawidłowa pozycja kursora Kursor powiązany z StatementHandle był zdefiniowany jako tylko do przekierowania, więc kursor nie mógł być umieszczony w zestawie wierszy. Zobacz opis atrybutu SQL_ATTR_CURSOR_TYPE w SQLSetStmtAttr.

Argument Operacja był SQL_UPDATE, SQL_DELETE lub SQL_REFRESH, a wiersz zidentyfikowany przez argument RowNumber został usunięty lub nie został pobrany.

(DM) Argument RowNumber wynosił 0, a argument Operacji SQL_POSITION.

SQLSetPos był wywoływany po wywołaniu SQLBulkOperations i przed wywołaniem SQLFetchScroll lub SQLFetch .
HY117 Połączenie jest zawieszone z powodu nieznanego stanu transakcji. Dozwolone są tylko funkcje rozłączania i tylko do odczytu. (DM) Aby uzyskać więcej informacji na temat stanu wstrzymania, zobacz SQLEndTran, funkcja.
HYC00 Opcjonalna funkcja nie zaimplementowana Sterownik lub źródło danych nie obsługuje operacji wymaganej w argumentach Operation ani LockType .
HYT00 Upłynął limit czasu Okres przekroczenia limitu czasu zapytania wygasł przed zwróceniem zestawu wyników przez źródło danych. Okres przekroczenia czasu jest ustalany przez SQLSetStmtAttr z atrybutem SQL_ATTR_QUERY_TIMEOUT.
HYT01 Upłynął limit czasu połączenia Okres przekroczenia limitu czasu połączenia wygasł, zanim źródło danych odpowiedziało na żądanie. Limit czasu połączenia jest ustawiany za pomocą parametru SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Sterownik nie obsługuje tej funkcji (DM) Sterownik skojarzony z instrukcją StatementHandle nie obsługuje funkcji.
IM017 Sondowanie jest wyłączone w trybie powiadomień asynchronicznych Za każdym razem, gdy jest używany model powiadomień, sondowanie jest wyłączone.
IM018 Funkcja SQLCompleteAsync nie została wywołana w celu ukończenia poprzedniej operacji asynchronicznej na tym dojściu. Jeśli poprzednie wywołanie funkcji na dojściu zwraca SQL_STILL_EXECUTING i jeśli tryb powiadomień jest włączony, narzędzie SQLCompleteAsync musi być wywoływane na dojściu, aby wykonać przetwarzanie końcowe i zakończyć operację.

Comments

Caution

Aby uzyskać informacje o tym, że można wywołać SQLSetPos oraz co jest konieczne dla kompatybilności z aplikacjami ODBC 2.x , zobacz kursorysy blokowe, przewijane kursory oraz kompatybilność wsteczną.

RowNumber Argument

Argument RowNumber określa liczbę wiersza w zestawie wierszy, na którym należy wykonać operację określoną przez argument Operacja . Jeśli argument RowNumber ma wartość 0, operacja ma zastosowanie do każdego wiersza w zestawie wierszy. RowNumber musi mieć wartość od 0 do liczby wierszy w zestawie wierszy.

Uwaga / Notatka

W języku C tablice są oparte na zerze, a argument RowNumber jest oparty na 1. Na przykład, aby zaktualizować piąty wiersz zestawu wierszy, aplikacja modyfikuje bufory wierszy na indeksie tablicy 4, ale określa Numer wiersza 5.

Wszystkie operacje umieszczają kursor na wierszu określonym przez RowNumber. Następujące operacje wymagają pozycji kursora:

  • Pozycjonowane instrukcje aktualizacji i usuwania.

  • Wywołania do SQLGetData.

  • Połączenia do SQLSetPos z opcjami SQL_DELETE, SQL_REFRESH i SQL_UPDATE.

Na przykład, jeśli RowNumber to 2 dla wywołania SQLSetPos z operacją SQL_DELETE, kursor jest umieszczony na drugim wierszu zestawu wierszy i ten wiersz jest usuwany. Wpis w tablicy statusu wiersza implementacji (wskazany przez atrybut SQL_ATTR_ROW_STATUS_PTR instrukcji) dla drugiego wiersza zostaje zmieniony na SQL_ROW_DELETED.

Aplikacja może określić pozycję kursora podczas wywoływania SQLSetPos. Zazwyczaj wywołuje SQLSetPos z operacją SQL_POSITION lub SQL_REFRESH, aby ustawić kursor przed wykonaniem pozycjonowanej instrukcji update lub delete albo wywołaniem SQLGetData.

Argument operacji

Argument Operacja wspiera następujące operacje. Aby określić, które opcje są obsługiwane przez dane źródło, aplikacja wywołuje SQLGetInfo za pomocą typów informacji SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 lub SQL_STATIC_CURSOR_ATTRIBUTES1 (w zależności od typu kursora).

Operation

argument
Operation
SQL_POSITION Sterownik ustawia kursor na wierszu określonym przez RowNumber.

Zawartość tablicy statusu wiersza, na którą wskazuje atrybut SQL_ATTR_ROW_OPERATION_PTR instrukcji, jest ignorowana w operacji SQL_POSITION.
SQL_REFRESH Sterownik umieszcza kursor na wierszu określonym przez RowNumber i odświeża dane w buforach wiersza dla tego wiersza. Aby uzyskać więcej informacji o tym, jak sterownik zwraca dane w buforach wiersza, zobacz opisy wiązania wierszowe i kolumnowe w SQLBindCol.

SQLSetPos z operacją SQL_REFRESH aktualizuje status i zawartość wierszy w aktualnie pobranym zestawie wierszy. To obejmuje odświeżanie zakładek. Ponieważ dane w buforach są odświeżane, ale nie pobierane ponownie, przynależność do zestawu wierszy jest stała. Różni się to od odświeżania wykonywanego przez wywołanie SQLFetchScroll z FetchOrientation równym SQL_FETCH_RELATIVE i RowNumber równym 0, które pobiera zestaw wierszy z zestawu wyników, aby wyświetlić dodatkowe dane i usunąć usunięte dane, jeśli te operacje są obsługiwane przez sterownik i kursor.

Pomyślne odświeżenie za pomocą SQLSetPos nie zmieni statusu wiersza SQL_ROW_DELETED. Usunięte wiersze w zbiorze wierszy będą nadal oznaczane jako usunięte aż do następnego pobierania. Wiersze znikną przy następnym pobieraniu, jeśli kursor obsługuje pakowanie (w którym kolejne SQLFetch lub SQLFetchScroll nie zwracają usuniętych wierszy).

Dodane wiersze nie pojawiają się po odświeżeniu za pomocą SQLSetPos . To zachowanie różni się od SQLFetchScroll z FetchType SQL_FETCH_RELATIVE i RowNumber równym 0, który również odświeża aktualny zestaw wierszy, ale pokaże dodatkowe rekordy lub usunięte rekordy, jeśli te operacje są obsługiwane przez kursor.

Pomyślne odświeżenie za pomocą SQLSetPos zmieni status wiersza SQL_ROW_ADDED na SQL_ROW_SUCCESS (jeśli istnieje tablica statusów wiersza).

Pomyślne odświeżenie za pomocą SQLSetPos zmieni status wiersza SQL_ROW_UPDATED na nowy status wiersza (jeśli istnieje tablica statusów wiersza).

Jeśli w operacji SQLSetPos wystąpi błąd na wierszu, status wiersza jest ustawiany na SQL_ROW_ERROR (jeśli istnieje tablica statusów wiersza).

Dla kursora otwartego z atrybutem SQL_ATTR_CONCURRENCY instrukcji SQL_CONCUR_ROWVER lub SQL_CONCUR_VALUES, odświeżenie za pomocą SQLSetPos może zaktualizować optymistyczne wartości współbieżności używane przez źródło danych, aby wykryć zmianę wiersza. Jeśli tak się stanie, wersje wierszy lub wartości używane do zapewnienia współbieżności kursora są aktualizowane za każdym razem, gdy bufory wierszy są odświeżane z serwera. Dzieje się to dla każdego odświeżonego wiersza.

Zawartość tablicy statusu wiersza wskazanej przez atrybut SQL_ATTR_ROW_OPERATION_PTR jest ignorowana w operacji SQL_REFRESH.
SQL_UPDATE Sterownik umieszcza kursor na wierszu określonym przez RowNumber i aktualizuje wiersz danych o wartości z buforów wiersza (argument TargetValuePtr w SQLBindCol). Pobiera długość danych z buforów długości/wskaźników (argument StrLen_or_IndPtr w SQLBindCol). Jeśli długość dowolnej kolumny wynosi SQL_COLUMN_IGNORE, kolumna nie jest aktualizowana. Po aktualizacji wiersza sterownik zmienia odpowiadający element tablicy statusu wiersza na SQL_ROW_UPDATED lub SQL_ROW_SUCCESS_WITH_INFO (jeśli istnieje tablica statusów wiersza).

Sterownik definiuje, jakie jest zachowanie, jeśli SQLSetPos z argumentem operacji SQL_UPDATE jest wywoływany na kursorze zawierającym zduplikowane kolumny. Sterownik może zwracać stan SQL zdefiniowany przez sterownik, aktualizować pierwszą kolumnę pojawiającą się w zbiorze wyników lub wykonywać inne zachowania zdefiniowane przez sterownik.

Tablica operacji wierszowych wskazana przez atrybut SQL_ATTR_ROW_OPERATION_PTR może być użyta do wskazania, że wiersz w bieżącym zestawie wierszy powinien być zignorowany podczas aktualizacji masowej. Więcej informacji można znaleźć w sekcji "Status and Operation Arrays" później w tym odwołaniu do funkcji.
SQL_DELETE Sterownik umieszcza kursor na wierszu określonym przez RowNumber i usuwa wiersz danych. Zmienia odpowiadający element tablicy statusu wiersza na SQL_ROW_DELETED. Po usunięciu wiersza następujące nie są ważne dla wiersza: pozycjonowane instrukcje update i delete, wywołania do SQLGetData oraz wywołania do SQLSetPos z operacją ustawioną na dowolne inne niż SQL_POSITION. W sterownikach obsługujących pakowanie, wiersz jest usuwany z kursora po pobieraniu nowych danych ze źródła danych.

To, czy wiersz pozostaje widoczny, zależy od typu kursora. Na przykład usunięte wiersze są widoczne dla statycznych i sterowanych przez zestaw klawiszy kursorów, ale niewidoczne dla dynamicznych kursorów.

Tablica operacji wierszowych wskazana przez atrybut SQL_ATTR_ROW_OPERATION_PTR może być użyta do wskazania, że wiersz w bieżącym zbiorze wierszy powinien zostać zignorowany podczas masowego usuwania. Więcej informacji można znaleźć w sekcji "Status and Operation Arrays" później w tym odwołaniu do funkcji.

Argument typu blokady

Argument LockType umożliwia aplikacjom kontrolę współbieżności. W większości przypadków źródła danych obsługujące poziomy współbieżności i transakcje będą wspierać jedynie wartość SQL_LOCK_NO_CHANGE argumentu LockType . Argument LockType jest zazwyczaj używany wyłącznie dla wsparcia opartego na plikach.

Argument LockType określa stan blokady wiersza po wykonaniu SQLSetPos . Jeśli sterownik nie jest w stanie zablokować wiersza ani w celu wykonania żądanej operacji, ani do spełnienia argumentu LockType , zwraca SQL_ERROR oraz SQLSTATE 42000 (błąd składni lub naruszenie dostępu).

Chociaż argument LockType jest określony dla pojedynczego zalecenia, zamek przyznaje te same uprawnienia wszystkim instrukcjom na połączeniu. W szczególności blokada uzyskana przez jedno zdanie na połączeniu może zostać odblokowana przez inne polecenie na tym samym połączeniu.

Wiersz zablokowany przez SQLSetPos pozostaje zablokowany, dopóki aplikacja nie wywoła SQLSetPos dla wiersza z LockType ustawionym na SQL_LOCK_UNLOCK lub dopóki aplikacja nie wywoła SQLFreeHandle dla polecenia lub SQLFreeStmt z opcją SQL_CLOSE. Dla sterownika obsługującego transakcje, wiersz zablokowany przez SQLSetPos jest odblokowywany, gdy aplikacja wywołuje SQLEndTran w celu zatwierdzenia lub cofnięcia transakcji na połączeniu (jeśli kursor jest zamknięty podczas zatwierdzania lub cofania transakcji, co wskazuje na typy informacji SQL_CURSOR_COMMIT_BEHAVIOR i SQL_CURSOR_ROLLBACK_BEHAVIOR zwracane przez SQLGetInfo).

Argument LockType wspiera następujące typy blokad. Aby określić, które blokady są obsługiwane przez źródło danych, aplikacja wywołuje SQLGetInfo za pomocą typów informacji SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 lub SQL_STATIC_CURSOR_ATTRIBUTES1 (w zależności od typu kursora).

Argument LockType Typ blokady
SQL_LOCK_NO_CHANGE Sterownik lub źródło danych zapewnia, że wiersz pozostaje w tym samym stanie zablokowanym lub odblokowanym, co przed wywołaniem SQLSetPos . Ta wartość LockType pozwala źródłom danych, które nie obsługują jawnego blokowania na poziomie wiersza, korzystanie z dowolnych bloków wymaganych przez obecne poziomy współbieżności i izolacji transakcji.
SQL_LOCK_EXCLUSIVE Sterownik lub źródło danych blokuje wiersz wyłącznie. Oświadczenie na innym połączeniu lub w innej aplikacji nie może być użyte do uzyskania jakichkolwiek blokad w wierszu.
SQL_LOCK_UNLOCK Sterownik lub źródło danych odblokowuje wiersz.

Jeśli sterownik obsługuje SQL_LOCK_EXCLUSIVE, ale nie obsługuje SQL_LOCK_UNLOCK, wiersz zablokowany pozostanie zablokowany do czasu wystąpienia jednego z wywołań opisanych w poprzednim akapicie.

Jeśli sterownik obsługuje SQL_LOCK_EXCLUSIVE, ale nie obsługuje SQL_LOCK_UNLOCK, wiersz zablokowany pozostanie zablokowany do momentu, gdy aplikacja wywoła SQLFreeHandle dla polecenia lub SQLFreeStmt z opcją SQL_CLOSE. Jeśli sterownik obsługuje transakcje i zamyka kursor podczas zatwierdzania lub cofania transakcji, aplikacja wywołuje SQLEndTran.

Do operacji aktualizacji i usuwania w SQLSetPos aplikacja używa argumentu LockType w następujący sposób:

  • Aby zagwarantować, że wiersz nie zmieni się po jego odzyskaniu, aplikacja wywołuje SQLSetPos z Operacją ustawioną na SQL_REFRESH i LockType na SQL_LOCK_EXCLUSIVE.

  • Jeśli aplikacja ustawi LockType na SQL_LOCK_NO_CHANGE, sterownik gwarantuje, że operacja aktualizacji lub usunięcia zakończy się tylko wtedy, gdy aplikacja określiła SQL_CONCUR_LOCK atrybutu SQL_ATTR_CONCURRENCY.

  • Jeśli aplikacja określa SQL_CONCUR_ROWVER lub SQL_CONCUR_VALUES dla atrybutu SQL_ATTR_CONCURRENCY, sterownik porównuje wersje wiersza lub wartości i odrzuca operację, jeśli wiersz zmienił się od momentu pobrania wiersza przez aplikację.

  • Jeśli aplikacja określi SQL_CONCUR_READ_ONLY dla atrybutu SQL_ATTR_CONCURRENCY, sterownik odrzuca każdą operację aktualizacji lub usunięcia.

Więcej informacji o atributie SQL_ATTR_CONCURRENCY statement można znaleźć w SQLSetStmtAttr.

Tablice statusu i operacji

Podczas wywoływania SQLSetPos stosuje się następujące tablice statusu i operacji:

  • Tablica statusów wiersza (wskazana przez pole SQL_DESC_ARRAY_STATUS_PTR w IRD oraz atrybut SQL_ATTR_ROW_STATUS_ARRAY instrukcji) zawiera wartości statusu dla każdego wiersza danych w zestawie wierszy. Sterownik ustawia wartości statusu w tej tablicy po wywołaniu do SQLFetch, SQLFetchScroll, SQLBulkOperations lub SQLSetPos. Na tę tablicę wskazuje atrybut SQL_ATTR_ROW_STATUS_PTR statement.

  • Tablica operacji wierszowych (wskazana przez pole SQL_DESC_ARRAY_STATUS_PTR w ARD oraz atrybut SQL_ATTR_ROW_OPERATION_ARRAY) zawiera wartość dla każdego wiersza w zbiorze wierszów, która wskazuje, czy wywołanie SQLSetPos w celu operacji masowej jest ignorowane, czy wykonywane. Każdy element w tablicy jest ustawiony na SQL_ROW_PROCEED (domyślnie) lub SQL_ROW_IGNORE. Na tę tablicę wskazuje atrybut SQL_ATTR_ROW_OPERATION_PTR statement.

Liczba elementów w tablicach statusu i operacji musi być równa liczbie wierszy w zbiorze wierszy (zgodnie z definicją atrybutu SQL_ATTR_ROW_ARRAY_SIZE instrukcji).

Aby uzyskać informacje o tablicy statusów wiersza, zobacz SQLFetch. Informacje o tablicy operacji wierszowych można znaleźć w artykule "Ignorowanie wiersza w operacji zbiorczej" później w tej sekcji.

Korzystanie z SQLSetPos

Zanim aplikacja wywoła SQLSetPos, musi wykonać następującą sekwencję kroków:

  1. Jeśli aplikacja wywoła SQLSetPos z Operacją ustawioną na SQL_UPDATE, wywołaj SQLBindCol (lub SQLSetDescRec) dla każdej kolumny, aby określić jej typ danych i powiązać bufory dla danych i długości kolumny.

  2. Jeśli aplikacja wywoła SQLSetPos z Operacją ustawioną na SQL_DELETE lub SQL_UPDATE, wywołaj SQLColAtribut , aby upewnić się, że kolumny do usunięcia lub aktualizacji są zaktualizowane.

  3. Zadzwoń do SQLExecDirect, SQLExecute lub funkcji katalogowej, aby utworzyć zbiór wyników.

  4. Zadzwoń do SQLFetch lub SQLFetchScroll , aby pobrać dane.

Więcej informacji o korzystaniu z SQLSetPos można znaleźć w artykule Aktualizacja danych za pomocą SQLSetPos.

Usuwanie danych za pomocą SQLSetPos

Aby usunąć dane w SQLSetPos, aplikacja wywołuje SQLSetPos z numerem wiersza ustawionym na numer wiersza do usunięcia i operacją ustawioną na SQL_DELETE.

Po usunięciu danych sterownik zmienia wartość w tablicy statusu wiersza implementacji dla odpowiedniego wiersza na SQL_ROW_DELETED (lub SQL_ROW_ERROR).

Aktualizacja danych za pomocą SQLSetPos

Aplikacja może przekazać wartość kolumny albo w buforze danych powiązanych, albo za pomocą jednego lub więcej wywołań do SQLPutData. Kolumny, których dane są przesyłane przez SQLPutData, nazywane są kolumnamidanych przy wykonaniu. Są one powszechnie używane do przesyłania danych dla kolumn SQL_LONGVARBINARY i SQL_LONGVARCHAR i mogą być mieszane z innymi kolumnami.

Aby zaktualizować dane za pomocą SQLSetPos, aplikacja:

  1. Umieszcza wartości w buforach danych oraz długości/wskaźników powiązanych z SQLBindCol:

    • Dla kolumn normalnych aplikacja umieszcza nową wartość kolumny w buforze *TargetValuePtr , a długość tej wartości w buforze *StrLen_or_IndPtr . Jeśli wiersz nie powinien być aktualizowany, aplikacja umieszcza SQL_ROW_IGNORE w elemencie tego wiersza w tablicy operacji wierszowych.

    • Dla kolumn danych podczas wykonania aplikacja umieszcza wartość zdefiniowaną przez aplikację, taką jak numer kolumny, w buforze *TargetValuePtr . Wartość ta może być później użyta do identyfikacji kolumny.

      Aplikacja umieszcza wynik makra SQL_LEN_DATA_AT_EXEC(długość) w buforze *StrLen_or_IndPtr . Jeśli typ danych SQL w kolumnie to SQL_LONGVARBINARY, SQL_LONGVARCHAR lub długi typ danych specyficzny dla źródła danych, a sterownik zwraca "Y" dla SQL_NEED_LONG_DATA_LEN typu informacji w SQLGetInfo, długość to liczba bajtów danych do wysłania dla parametru; w przeciwnym razie musi to być wartość nieujemna i jest ignorowana.

  2. Wywołuje SQLSetPos z argumentem Operation ustawionym na SQL_UPDATE, aby zaktualizować wiersz danych.

    • Jeśli nie ma kolumn danych przy wykonaniu, proces jest zakończony.

    • Jeśli istnieją kolumny danych przy wykonaniu, funkcja zwraca SQL_NEED_DATA i przechodzi do kroku 3.

  3. Wywołuje SQLParamData , aby pobrać adres bufora *TargetValuePtr dla pierwszej przetworzonej kolumny danych przy wykonaniu. SQLParamData zwraca SQL_NEED_DATA. Aplikacja pobiera wartość zdefiniowaną przez aplikację z bufora *TargetValuePtr .

    Uwaga / Notatka

    Chociaż parametry danych przy wykonaniu są podobne do kolumn danych przy wykonywaniu, wartość zwracana przez SQLParamData jest inna dla każdej z nich.

    Uwaga / Notatka

    Parametry danych przy wykonaniu to parametry w instrukcji SQL, dla których dane zostaną wysłane wraz z SQLPutData podczas wykonywania instrukcji SQLExecDirect lub SQLExecute. Są one powiązane z SQLBindParameter lub przez ustawianie deskryptorów w SQLSetDescRec. Wartość zwracana przez SQLParamData to 32-bitowa wartość przekazywana do SQLBindParameter w argumentze ParameterValuePtr .

    Uwaga / Notatka

    Kolumny danych przy wykonaniu to kolumny w zestawie wierszy, dla których dane będą wysyłane wraz z SQLPutData po aktualizacji wiersza za pomocą SQLSetPos. Są powiązane z SQLBindCol. Wartość zwracana przez SQLParamData to adres wiersza w buforze *TargetValuePtr , który jest przetwarzany.

  4. Wywołuje SQLPutData jeden lub więcej razy, aby przesłać dane do kolumny. Potrzeba więcej niż jednego wywołania, jeśli wszystkie wartości danych nie mogą zostać zwrócone w buforze *TargetValuePtr określonym w SQLPutData; wielokrotne wywołania do SQLPutData dla tej samej kolumny są dozwolone tylko przy wysyłaniu danych znaku C do kolumny zawierającej typ danych znakowy, binarny lub specyficzny dla źródła danych, albo przy wysyłaniu danych binarnych C do kolumny zawierającej typ danych ze znakiem, binarnym lub specyficznym dla źródła danych.

  5. Ponownie wywołuje SQLParamData , aby zasygnalizować, że wszystkie dane zostały wysłane do kolumny.

    • Jeśli jest więcej kolumn danych podczas wykonywania, SQLParamData zwraca SQL_NEED_DATA oraz adres bufora TargetValuePtr dla kolejnej kolumny danych przy wykonywaniu danych, którą ma się przetworzyć. Aplikacja powtarza kroki 4 i 5.

    • Jeśli nie ma już kolumn danych przy wykonaniu, proces jest zakończony. Jeśli instrukcja została pomyślnie wykonana, SQLParamData zwraca SQL_SUCCESS lub SQL_SUCCESS_WITH_INFO; jeśli wykonanie się nie powiodło, zwraca SQL_ERROR. W tym momencie SQLParamData może zwrócić dowolny stan SQL, który SQLSetPos może zwrócić.

Jeśli dane zostały zaktualizowane, sterownik zmienia wartość w tablicy statusu wiersza implementacji dla odpowiedniego wiersza na SQL_ROW_UPDATED.

Jeśli operacja zostanie anulowana lub wystąpi błąd w SQLParamData lub SQLPutData, po zwrotie SQL_NEED_DATA przez SQLSetPos i przed wysłaniem danych dla wszystkich kolumn danych przy wykonaniu, aplikacja może wywołać tylko SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions, SQLParamData lub SQLPutData dla polecenia lub połączenia powiązanego z daną instrukcją. Jeśli wywoła inną funkcję dla polecenia lub powiązania z tym zdaniem, funkcja zwraca SQL_ERROR oraz SQLSTATE HY010 (błąd sekwencji funkcji).

Jeśli aplikacja wywołuje SQLCancel , gdy sterownik nadal potrzebuje danych dla kolumn danych podczas wykonywania, sterownik anuluje operację. Aplikacja może następnie ponownie wywołać SQLSetPos ; Anulowanie nie wpływa na stan kursora ani na aktualną pozycję kursora.

Gdy lista SELECT-lista specyfikacji zapytania powiązanej z kursorem zawiera więcej niż jedno odwołanie do tej samej kolumny, to czy wygenerowany jest błąd, czy sterownik ignoruje zduplikowane odwołania i wykonuje żądane operacje, jest definiowane przez sterownik.

Wykonywanie operacji masowych

Jeśli argument RowNumber wynosi 0, sterownik wykonuje operację określoną w argumentze Operation dla każdego wiersza w zbiorze wierszy, który ma wartość SQL_ROW_PROCEED w polu w tablicy operacji wierszowej, wskazywanej przez atrybut SQL_ATTR_ROW_OPERATION_PTR instrukcji. Jest to prawidłowa wartość argumentu RowNumber dla argumentu Operation o wartości SQL_DELETE, SQL_REFRESH lub SQL_UPDATE, ale nie SQL_POSITION. SQLSetPos z operacją SQL_POSITION i RowNumber równym 0 zwróci SQLSTATE HY109 (Nieprawidłowa pozycja kursora).

Jeśli wystąpi błąd dotyczący całego zestawu wierszy, na przykład SQLSTATE HYT00 (Timeout expired), sterownik zwraca SQL_ERROR oraz odpowiedni SQLSTATE. Zawartość buforów wierszy jest niezdefiniowana, a pozycja kursora pozostaje niezmieniona.

Jeśli wystąpi błąd dotyczący pojedynczego wiersza, sterownik:

  • Ustawia element wiersza w tablicy statusów wiersza, na który wskazuje atrybut SQL_ATTR_ROW_STATUS_PTR instrukcji, na SQL_ROW_ERROR.

  • Publikuje jeden lub więcej dodatkowych stanów SQL dla błędu w kolejce błędów i ustawia pole SQL_DIAG_ROW_NUMBER w strukturze danych diagnostycznych.

Po przetworzeniu błędu lub ostrzeżenia, jeśli sterownik wykona operację dla pozostałych wierszy w zestawie wierszy, zwraca SQL_SUCCESS_WITH_INFO. W związku z tym dla każdego wiersza, który zwrócił błąd, kolejka błędów zawiera zero lub więcej dodatkowych stanów SQL. Jeśli sterownik zatrzyma operację po przetworzeniu błędu lub ostrzeżenia, zwraca SQL_ERROR.

Jeśli sterownik zwraca jakiekolwiek ostrzeżenia, takie jak SQLSTATE 01004 (Data Truncated), zwraca ostrzeżenia dotyczące całego zestawu wierszy lub nieznanych wierszy w zestawie, zanim zwróci informacje o błędzie odnoszące się do konkretnych wierszy. Zwraca ostrzeżenia dla konkretnych wierszy wraz z innymi informacjami o błędach dotyczących tych wierszy.

Jeśli RowNumber jest równy 0, a Operacja to SQL_UPDATE, SQL_REFRESH lub SQL_DELETE, liczba wierszy, na których działa SQLSetPos , jest wskazana przez atrybut SQL_ATTR_ROWS_FETCHED_PTR.

Jeśli RowNumber jest równy 0, a Operacja to SQL_DELETE, SQL_REFRESH lub SQL_UPDATE, bieżący wiersz po operacji jest taki sam jak aktualny wiersz przed operacją.

Ignorowanie wiersza w operacji masowej

Tablica operacji wierszowych może być użyta do wskazania, że wiersz w bieżącym zestawie wierszy powinien być zignorowany podczas operacji masowej przy użyciu SQLSetPos. Aby nakazać sterownikowi ignorowanie jednego lub więcej wierszy podczas operacji masowej, aplikacja powinna wykonać następujące kroki:

  1. Wywołaj SQLSetStmtAttr , aby ustawić atrybut SQL_ATTR_ROW_OPERATION_PTR jako wskazujący na tablicę SQLUSMALLINT. To pole można również ustawić, wywołując SQLSetDescField , aby ustawić pole nagłówka SQL_DESC_ARRAY_STATUS_PTR ARD, co wymaga, aby aplikacja uzyskała uchwyt deskryptoru.

  2. Ustaw każdy element tablicy operacji wierszowych na jedną z dwóch wartości:

    • SQL_ROW_IGNORE, aby wskazać, że wiersz jest wykluczony dla operacji masowej.

    • SQL_ROW_PROCEED, aby wskazać, że wiersz jest uwzględniony w operacji zbiorczej. (Jest to wartość domyślna).

  3. Zadzwoń do SQLSetPos, aby wykonać operację masową.

Następujące zasady dotyczą tablicy operacji wierszowych:

  • SQL_ROW_IGNORE i SQL_ROW_PROCEED wpływają wyłącznie na operacje masowe z użyciem SQLSetPos z operacją SQL_DELETE lub SQL_UPDATE. Nie wpływają one na wywołania do SQLSetPos przy operacji SQL_REFRESH lub SQL_POSITION.

  • Wskaźnik jest domyślnie ustawiony na null.

  • Jeśli wskaźnik jest null, wszystkie wiersze są aktualizowane tak, jakby wszystkie elementy były ustawione na SQL_ROW_PROCEED.

  • Ustawienie elementu na SQL_ROW_PROCEED nie gwarantuje, że operacja zostanie wykonana w tym konkretnym wierszu. Na przykład, jeśli dany wiersz w zestawie wierszy ma status SQL_ROW_ERROR, sterownik może nie być w stanie go zaktualizować, niezależnie od SQL_ROW_PROCEED tego, czy aplikacja to określiła. Aplikacja musi zawsze sprawdzić tablicę statusu wiersza, aby sprawdzić, czy operacja zakończyła się sukcesem.

  • SQL_ROW_PROCEED jest zdefiniowane jako 0 w pliku nagłówkowym. Aplikacja może zaiinicjować tablicę operacji wierszowych do zera, aby przetworzyć wszystkie wiersze.

  • Jeśli element numer "n" w tablicy operacji wiersza jest ustawiony na SQL_ROW_IGNORE i wywołany zostanie SQLSetPos do wykonania operacji aktualizacji lub usunięcia masowo, n-ty wiersz w zestawie wierszy pozostaje niezmieniony po wywołaniu do SQLSetPos.

  • Aplikacja powinna automatycznie ustawić kolumnę tylko do odczytu na SQL_ROW_IGNORE.

Ignorowanie kolumny w operacji zbiorczej

Aby uniknąć niepotrzebnej diagnostyki generowanej przez próby aktualizacji jednej lub więcej kolumn tylko do odczytu, aplikacja może ustawić wartość w buforze długości bound/indicator na SQL_COLUMN_IGNORE. Więcej informacji można znaleźć w SQLBindCol.

Przykład kodu

W poniższym przykładzie aplikacja pozwala użytkownikowi przeglądać tabelę ORDERS i aktualizować status zamówienia. Kursor jest sterowany zestawem klawiszy o rozmiarze 20 wierszy i wykorzystuje optymistyczną kontrolę współbieżności porównującej wersy wierszy. Po pobraniu każdego zestawu wierszy aplikacja go drukuje i pozwala użytkownikowi wybrać oraz zaktualizować status zamówienia. Aplikacja wykorzystuje SQLSetPos do ustawienia kursora na wybrany wiersz i wykonuje aktualizację wiersza pozycjonowaną. (Obsługa błędów została pominięta dla jasności.)

#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;  
      }  
   }  
}  

Więcej przykładów można znaleźć w artykule Pozycjonowane instrukcje Update i Delete oraz Aktualizowanie wierszy w zestawie wierszy z pomocą SQLSetPos.

Aby uzyskać informacje o Zobacz
Wiązanie buforu z kolumną w zestawie wyników SQLBindCol, funkcja
Wykonywanie operacji masowych niezwiązanych z pozycją kursora blokowego Funkcja SQLBulkOperations
Anulowanie przetwarzania instrukcji SQLCancel, funkcja
Pobieranie bloku danych lub przewijanie zestawu wyników SQLFetchScroll, funkcja
Uzyskanie pojedynczego pola deskryptora Funkcja SQLGetDescField
Uzyskanie wielu pól deskryptora Funkcja SQLGetDescRec
Ustawianie pojedynczego pola deskryptora Funkcja SQLSetDescField
Ustawianie wielu pól deskryptora Funkcja SQLSetDescRec
Ustawianie atrybutu instrukcji SQLSetStmtAttr, funkcja