SQLSetPos-funktion

Överensstämmelse
Version introducerad: ODBC 1.0 Standardefterlevnad: ODBC

Summary
SQLSetPos sätter markörpositionen i en raduppsättning och tillåter en applikation att uppdatera data i raduppsättningen eller uppdatera eller ta bort data i resultatuppsättningen.

Syntax

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

Arguments

StatementHandle
[Indata] Instruktionshandtag.

RowNumber
[Input] Positionen för raden i radmängden på vilken operationen som anges med Operation-argumentet ska utföras. Om RowNumber är 0 gäller åtgärden för varje rad i raduppsättningen.

För ytterligare information, se "Kommentarer."

Operation
[Input] Operation att utföra:

SQL_POSITION SQL_REFRESH SQL_UPDATE SQL_DELETE

Anmärkning

SQL_ADD-värdet för Operation-argumentet har föråldrats för ODBC 3.x. ODBC 3.x-drivrutiner måste stödja SQL_ADD för bakåtkompatibilitet. Denna funktionalitet har ersatts av ett anrop till SQLBulkOperations med en Operation SQL_ADD. När en ODBC 3.x-applikation arbetar med en ODBC 2.x-drivrutin , mappar Driver Manager ett anrop till SQLBulkOperations med en Operation SQL_ADD till SQLSetPos med en Operation SQL_ADD.

För mer information, se "Kommentarer."

LockType
[Input] Specificerar hur raden ska låsas efter att operationen som anges i Operation-argumentet har utförts.

SQL_LOCK_NO_CHANGE SQL_LOCK_EXCLUSIVE SQL_LOCK_UNLOCK

För mer information, se "Kommentarer."

Returns

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

Diagnostics

När SQLSetPos returnerar SQL_ERROR eller SQL_SUCCESS_WITH_INFO kan ett associerat SQLSTATE-värde erhållas genom att anropa SQLGetDiagRec med HandleType SQL_HANDLE_STMT och Handle of StatementHandle. Följande tabell listar de SQLSTATE-värden som vanligtvis returneras av SQLSetPos och förklarar var och en i kontexten av denna funktion; notationen "(DM)" föregår beskrivningarna av SQLSTATE som returneras av Driver Manager. Returkoden som är associerad med varje SQLSTATE-värde är SQL_ERROR, om inget annat anges.

För alla SQLSTATES som kan returnera SQL_SUCCESS_WITH_INFO eller SQL_ERROR (förutom 01xxx SQLSTATE) returneras SQL_SUCCESS_WITH_INFO om ett fel uppstår på en eller flera, men inte alla, rader i en flerradsoperation, och SQL_ERROR returneras om ett fel uppstår i en enradsoperation.

SQLSTATE Error Description
01000 Allmän varning Informationsmeddelande för drivrutinsspecifikt. (Funktionen returnerar SQL_SUCCESS_WITH_INFO.)
01001 Marköråtgärdskonflikt Operation-argumentet var SQL_DELETE eller SQL_UPDATE, och inga rader eller mer än en rad raderades bort eller uppdaterades. (För mer information om uppdateringar av mer än en rad, se beskrivningen av attributet SQL_ATTR_SIMULATE_CURSOR iSQLSetStmtAttr.) (Funktionen returnerar SQL_SUCCESS_WITH_INFO.)

Operationens argument var SQL_DELETE eller SQL_UPDATE, och operationen misslyckades på grund av optimistisk samkörning. (Funktionen returnerar SQL_SUCCESS_WITH_INFO.)
01004 Högeravskärning av strängdata Operation-argumentet var SQL_REFRESH, och sträng- eller binärdata returnerades för en kolumn eller kolumner med en datatyp av SQL_C_CHAR eller SQL_C_BINARY resulterade i trunkering av icke-blanka tecken eller icke-NULL-binärdata.
01S01 Fel i rad RowNumber-argumentet var 0, och ett fel uppstod i en eller flera rader när operationen specificerades med Operation-argumentet utfördes.

(SQL_SUCCESS_WITH_INFO returneras om ett fel uppstår på en eller flera, men inte alla, rader i en flerradsoperation, och SQL_ERROR returneras om ett fel uppstår i en enradsoperation.)

(Denna SQLSTATE returneras endast när SQLSetPos anropas efter SQLExtendedFetch, om drivrutinen är en ODBC 2.x-drivrutin och markörbiblioteket inte används.)
01S07 Fraktionell trunkering Operation-argumentet var SQL_REFRESH, datatypen i applikationsbufferten var varken SQL_C_CHAR eller SQL_C_BINARY, och datan som returnerades till applikationsbuffertar för en eller flera kolumner var avskuren. För numeriska datatyper förkortades den bråkdelade delen av talet. För tids-, tidsstämpel- och intervalldatatyper som innehåller en tidskomponent förkortades den bråkdelade delen av tiden.

(Funktionen returnerar SQL_SUCCESS_WITH_INFO.)
07006 Attributöverträdelse för begränsad datatyp Datavärdet för en kolumn i resultatuppsättningen kunde inte konverteras till den datatyp som specificerades av TargetType i anropet till SQLBindCol.
07009 Ogiltigt deskriptorindex Argumentoperationen var SQL_REFRESH eller SQL_UPDATE, och en kolumn var bunden med ett kolumnnummer större än antalet kolumner i resultatuppsättningen.
21S02 Graden av härledd tabell matchar inte kolumnlistan Argumentet Operation var SQL_UPDATE, och inga kolumner kunde uppdateras eftersom alla kolumner antingen var obundna, skrivskyddade, eller värdet i bunden längd/indikatorbuffert var SQL_COLUMN_IGNORE.
22001 Strängdata, höger trunkering Operation-argumentet var SQL_UPDATE, och tilldelningen av ett tecken eller binärt värde till en kolumn resulterade i att icke-blanka (för tecken) eller icke-null (för binära) tecken eller byte förkortades.
22003 Numeriskt värde som ligger utom intervallet Argumentoperationen var SQL_UPDATE, och tilldelningen av ett numeriskt värde till en kolumn i resultatmängden gjorde att hela (till skillnad från bråkdels) delen av talet avkortades.

Argumentet Operation var SQL_REFRESH, och att returnera det numeriska värdet för en eller flera bundna kolumner skulle ha orsakat förlust av betydande siffror.
22007 Ogiltigt datetime-format Argumentet Operation var SQL_UPDATE, och tilldelningen av ett datum eller tidsstämpelvärde till en kolumn i resultatuppsättningen gjorde att fältet för år, månad eller dag låg utanför intervallet.

Argumentet Operation var SQL_REFRESH, och att returnera datum- eller tidsstämpelvärdet för en eller flera bundna kolumner skulle ha gjort att fältet för år, månad eller dag hamnade utanför intervallet.
22008 Datum/tid-fältöverflöd Operation-argumentet var SQL_UPDATE, och prestandan för datumtidsaritmetik på data som skickades till en kolumn i resultatuppsättningen resulterade i att ett datumtidsfält (år, månad, dag, timme, minut eller sekundfält) för resultatet låg utanför det tillåtna värdeintervallet för fältet, eller var ogiltigt enligt den gregorianska kalenderns naturliga regler för datumtider.

Operation-argumentet var SQL_REFRESH, och prestandan av datetime-aritmetik på data som hämtades från resultatmängden resulterade i att ett datetime-fält (år, månad, dag, timme, minut eller andra fält) av resultatet låg utanför det tillåtna värdeintervallet för fältet, eller var ogiltigt enligt den gregorianska kalenderns naturliga regler för date-times.
22015 Intervallfältsspill Operation-argumentet var SQL_UPDATE, och tilldelningen av en exakt numerisk eller intervall C-typ till en intervall-SQL-datatyp orsakade förlust av betydande siffror.

Operation-argumentet var SQL_UPDATE; vid tilldelning till en intervall-SQL-typ fanns ingen representation av värdet på C-typen i intervall-SQL-typen.

Operation-argumentet var SQL_REFRESH, och tilldelning från en exakt numerisk eller intervall SQL-typ till en intervall C-typ orsakade förlust av betydande siffror i det ledande fältet.

Operation-argumentet var SQL_ REFRESH; vid tilldelning av en intervalltyp C fanns ingen representation av värdet på SQL-typen i intervall C-typen.
22018 Ogiltigt teckenvärde för gjuten specifikation Operation-argumentet var SQL_REFRESH; C-typen var en exakt eller ungefärlig numerisk typ, en date-time eller en intervalldatatyp; kolumnens SQL-typ var en teckendatatyp; och värdet i kolumnen var inte en giltig literal av den bundna typen C.

Argumentet Operation var SQL_UPDATE; SQL-typen var en exakt eller ungefärlig numerisk, en date-time eller en intervalldatatyp; C-typen var SQL_C_CHAR; och värdet i kolumnen var inte en giltig literal av den bundna SQL-typen.
23000 Integritetsbegränsningsöverträdelse Argumentet Operation var SQL_DELETE eller SQL_UPDATE, och en integritetsbegränsning bröts.
24000 Ogiltigt markörtillstånd StatementHandle var i ett exekverat tillstånd, men ingen resultatuppsättning var kopplad till StatementHandle.

(DM) En markör var öppen på StatementHandle, men SQLFetch eller SQLFetchScroll hade inte anropats.

En markör var öppen på StatementHandle, och SQLFetch eller SQLFetchScroll hade anropats, men markören var placerad före starten av resultatuppsättningen eller efter resultatuppsättningens slut.

Argumentoperationen var SQL_DELETE, SQL_REFRESH eller SQL_UPDATE, och markören placerades före början av resultatmängden eller efter resultatmängdens slut.
40001 Serialiseringsfel Transaktionen återställdes på grund av ett resursstopp med en annan transaktion.
40003 Slutförande av instruktion okänd Den associerade anslutningen misslyckades under körningen av den här funktionen och transaktionens tillstånd kan inte fastställas.
42000 Syntaxfel eller åtkomstöverträdelse Föraren kunde inte låsa raden som behövdes för att utföra den operation som efterfrågades i argumentet Operation.

Föraren kunde inte låsa raden som begärts i argumentet LockType.
44000 MED KONTROLLALTERNATIVsöverträdelse Operation-argumentet var SQL_UPDATE, och uppdateringen utfördes på en visad tabell eller en tabell härledd från den visade tabellen som skapades genom att specificera MED CHECK OPTION, så att en eller flera rader som påverkades av uppdateringen inte längre finns i den visade tabellen.
HY000 Allmänt fel Ett fel uppstod för vilket det inte fanns någon specifik SQLSTATE och för vilken ingen implementeringsspecifik SQLSTATE definierades. Felmeddelandet som returnerades av SQLGetDiagRec i *MessageText-bufferten beskriver felet och dess orsak.
HY001 Fel vid minnesallokering Drivrutinen kunde inte allokera minne som krävs för körning eller slutförande av funktionen.
HY008 Åtgärden avbröts Asynkron bearbetning aktiverades för StatementHandle. Funktionen anropades, och innan exekveringen var klar anropades SQLCancel eller SQLCancelHandleStatementHandle, och sedan anropades funktionen igen på StatementHandle.

Funktionen anropades och innan körningen slutfördes anropades SQLCancel eller SQLCancelHandleStatementHandle från en annan tråd i ett flertrådsprogram.
HY010 Funktionssekvensfel (DM) En asynkront körande funktion anropades för anslutningshandtaget som är associerat med StatementHandle. Denna asynkrona funktion kördes fortfarande när SQLSetPos-funktionen anropades.

(DM) Den specificerade StatementHandle var inte i ett exekverat tillstånd. Funktionen anropades utan att först anropa SQLExecDirect, SQLExecute eller en katalogfunktion.

(DM) En asynkront körande funktion (inte den här) anropades för StatementHandle och kördes fortfarande när den här funktionen anropades.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations eller SQLSetPos anropades för StatementHandle och returnerades SQL_NEED_DATA. Den här funktionen anropades innan data skickades för alla data-at-execution-parametrar eller kolumner.

(DM) Drivrutinen var en ODBC 2.x-drivrutin , och SQLSetPos anropades för en StatementHandle efter att SQLFetch anropats.
HY011 Attributet kan inte sättas nu (DM) Drivrutinen var en ODBC 2.x-drivrutin ; attributet SQL_ATTR_ROW_STATUS_PTR sats sattes; sedan anropades SQLSetPos innan SQLFetch, SQLFetchScroll eller SQLExtendedFetch kallades upp.
HY013 Minneshanteringsfel Det gick inte att bearbeta funktionsanropet eftersom det inte gick att komma åt underliggande minnesobjekt, möjligen på grund av minnesbrist.
HY090 Ogiltig sträng- eller buffertlängd Operation-argumentet var SQL_UPDATE, ett datavärde var en nullpekare, och kolumnlängdsvärdet var inte 0, SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NULL_DATA eller mindre än eller lika med SQL_LEN_DATA_AT_EXEC_OFFSET.

Operation-argumentet var SQL_UPDATE; ett datavärde var inte en nullpekare; C-datatypen var SQL_C_BINARY eller SQL_C_CHAR; och kolumnlängdsvärdet var mindre än 0 men inte lika med SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NTS eller SQL_NULL_DATA, eller mindre än eller lika med SQL_LEN_DATA_AT_EXEC_OFFSET.

Värdet i en längd-/indikatorbuffert var SQL_DATA_AT_EXEC; SQL-typen var antingen SQL_LONGVARCHAR, SQL_LONGVARBINARY eller en lång datakällsspecifik datatyp; och den SQL_NEED_LONG_DATA_LEN informationstypen i SQLGetInfo var "Y".
HY092 Ogiltig attributidentifierare (DM) Värdet som angavs för Operation-argumentet var ogiltigt.

(DM) Värdet som specificerades för LockType-argumentet var ogiltigt.

Operation-argumentet var SQL_UPDATE eller SQL_DELETE, och attributet SQL_ATTR_CONCURRENCY statement var SQL_ATTR_CONCUR_READ_ONLY.
HY107 Radvärde utanför räckvidden Värdet som angavs för argumentet RowNumber var större än antalet rader i raduppsättningen.
HY109 Ogiltig markörposition Markören kopplad till StatementHandle definierades som framåtriktad, så markören kunde inte placeras inom raduppsättningen. Se beskrivningen för attributet SQL_ATTR_CURSOR_TYPE i SQLSetStmtAttr.

Operation-argumentet var SQL_UPDATE, SQL_DELETE eller SQL_REFRESH, och raden som identifierades av RowNumber-argumentet hade tagits bort eller hade inte hämtats.

(DM) RowNumber-argumentet var 0, och Operation-argumentet var SQL_POSITION.

SQLSetPos anropades efter att SQLBulkOperations kallades och innan SQLFetchScroll eller SQLFetch anropades.
HY117 Anslutningen pausas på grund av okänt transaktionstillstånd. Endast frånkopplings- och skrivskyddade funktioner tillåts. (DM) Mer information om pausat tillstånd finns i SQLEndTran-funktion.
HYC00 Valfri funktion har inte implementerats Drivrutinen eller datakällan stöder inte den operation som begärs i Operation-argumentet eller LockType-argumentet .
HYT00 Tidsgränsen har upphört att gälla Tidsgränsen för frågan upphörde att gälla innan datakällan returnerade resultatuppsättningen. Timeout-perioden sätts genom SQLSetStmtAttrmed attributet SQL_ATTR_QUERY_TIMEOUT.
HYT01 Tidsgränsen för anslutningen gick ut Tidsgränsen för anslutningen löpte ut innan datakällan svarade på begäran. Tidsgränsen för anslutningen anges via SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Drivrutinen stöder inte den här funktionen (DM) Drivrutinen som är associerad med StatementHandle stöder inte funktionen.
IM017 Avsökning är inaktiverat i asynkront meddelandeläge När meddelandemodellen används inaktiveras avsökningen.
IM018 SQLCompleteAsync har inte anropats för att slutföra den tidigare asynkrona åtgärden på det här handtaget. Om det tidigare funktionsanropet på handtaget returnerar SQL_STILL_EXECUTING och om meddelandeläget är aktiverat måste SQLCompleteAsync anropas på handtaget för att utföra efterbearbetningen och slutföra åtgärden.

Comments

Försiktighet

För information om vad uttalandet anger att SQLSetPos kan anropas och vad det behöver göra för kompatibilitet med ODBC 2.x-applikationer , se Block Cursors, Scrollable Cursors, and Backward Compatibility.

RowNumber-argumentet

Argumentet RowNumber specificerar numret på raden i radmängden där operationen som anges av argumentet Operation ska utföras. Om RowNumber är 0 gäller åtgärden för varje rad i raduppsättningen. RowNumber måste vara ett värde från 0 till antalet rader i radmängden.

Anmärkning

I C-språket är arrayerna 0-baserade och RowNumber-argumentet är 1-baserat. Till exempel, för att uppdatera den femte raden i raduppsättningen, modifierar en applikation raduppsättningsbuffertarna vid arrayindex 4 men anger ett RowNumber på 5.

Alla operationer placerar markören på raden som anges av RowNumber. Följande operationer kräver en markörposition:

  • Positionerade uppdaterings- och borttagningssatser.

  • Anrop till SQLGetData.

  • Anrop till SQLSetPos med alternativen SQL_DELETE, SQL_REFRESH och SQL_UPDATE.

Till exempel, om RowNumber är 2 för ett anrop till SQLSetPos med en Operation SQL_DELETE, placeras markören på den andra raden i radmängden och den raden tas bort. Posten i implementationsradens statusarray (pekad till av attributet SQL_ATTR_ROW_STATUS_PTR-satsen) för den andra raden ändras till SQL_ROW_DELETED.

En applikation kan ange en markörposition när den anropar SQLSetPos. Generellt anropar den SQLSetPos med operationen SQL_POSITION eller SQL_REFRESH för att positionera markören innan en positionerad uppdatering eller delete-sats körs eller anropas SQLGetData.

Operation Argument

Operation-argumentet stöder följande operationer. För att avgöra vilka alternativ som stöds av en datakälla anropar en applikation SQLGetInfo med informationstypen SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 eller SQL_STATIC_CURSOR_ATTRIBUTES1 (beroende på markörens typ).

Operation

argument
Operation
SQL_POSITION Föraren placerar markören på raden som anges av RowNumber.

Innehållet i radstatusarrayen som pekas på av attributet SQL_ATTR_ROW_OPERATION_PTR statement ignoreras för SQL_POSITION Operation.
SQL_REFRESH Drivrutinen placerar markören på raden som anges av RowNumber och uppdaterar data i raduppsättningens buffertar för den raden. För mer information om hur drivrutinen returnerar data i raduppsättningsbuffertarna, se beskrivningarna av radvis och kolumnvis bindning i SQLBindCol.

SQLSetPos med en Operation SQL_REFRESH uppdaterar status och innehåll för raderna inom den aktuella hämtade raduppsättningen. Detta inkluderar att uppdatera bokmärken. Eftersom datan i buffertarna uppdateras men inte återhämtas, är medlemskapet i radmängden fast. Detta skiljer sig från den uppdatering som utförs av ett anrop till SQLFetchScroll med FetchOrientation på SQL_FETCH_RELATIVE och ett RowNumber lika med 0, vilket refererar radmängden från resultatuppsättningen så att den kan visa tillagd data och ta bort borttagen data om dessa operationer stöds av drivrutinen och markören.

En lyckad uppdatering med SQLSetPos ändrar inte radstatusen SQL_ROW_DELETED. Raderade rader inom raduppsättningen kommer fortsatt att markeras som raderade tills nästa hämtning. Raderna försvinner vid nästa hämtning om markören stödjer packning (där en efterföljande SQLFetch eller SQLFetchScroll inte returnerar rader).

Tillagda rader visas inte när en uppdatering med SQLSetPos utförs. Detta beteende skiljer sig från SQLFetchScroll med en FetchType SQL_FETCH_RELATIVE och ett RowNumber lika med 0, som också uppdaterar den aktuella raduppsättningen men visar tillagda poster eller paketraderade poster om dessa operationer stöds av markören.

En lyckad uppdatering med SQLSetPos ändrar radstatusen SQL_ROW_ADDED till SQL_ROW_SUCCESS (om radstatusarrayen finns).

En lyckad uppdatering med SQLSetPos ändrar radstatusen SQL_ROW_UPDATED till radens nya status (om radstatusarrayen finns).

Om ett fel uppstår i en SQLSetPos-operation på en rad sätts radstatusen till SQL_ROW_ERROR (om radstatusarrayen finns).

För en markör som öppnas med ett attribut SQL_ATTR_CONCURRENCY sats SQL_CONCUR_ROWVER eller SQL_CONCUR_VALUES kan en uppdatering med SQLSetPos uppdatera de optimistiska samtidighetsvärden som används av datakällan för att upptäcka att raden har ändrats. Om detta sker uppdateras radversionerna eller värdena som används för att säkerställa markörens samtidighet varje gång raduppsättningsbuffertarna uppdateras från servern. Detta sker för varje rad som uppdateras.

Innehållet i radstatusarrayen som pekas på av attributet SQL_ATTR_ROW_OPERATION_PTR statement ignoreras för SQL_REFRESH Operation.
SQL_UPDATE Drivrutinen placerar markören på raden som specificeras av RowNumber och uppdaterar den underliggande dataraden med värdena i raduppsättningsbuffertarna (argumentet TargetValuePtr i SQLBindCol). Den hämtar datans längder från buffertarna för längd/indikator (det StrLen_or_IndPtr argumentet i SQLBindCol). Om längden på någon kolumn är SQL_COLUMN_IGNORE uppdateras kolumnen inte. Efter att raden har uppdaterats ändrar drivrutinen motsvarande element i radstatusarrayen till SQL_ROW_UPDATED eller SQL_ROW_SUCCESS_WITH_INFO (om radstatusarrayen finns).

Det är drivrutinsdefinierat vad beteendet är om SQLSetPos med ett Operation-argument SQL_UPDATE anropas på en markör som innehåller dubblettkolumner. Drivrutinen kan returnera ett drivrutinsdefinierad SQLSTATE, uppdatera den första kolumnen som visas i resultatuppsättningen, eller utföra annat drivrutinsdefinierad beteende.

Raden operationsarrayen som pekas på av attributet SQL_ATTR_ROW_OPERATION_PTR statement kan användas för att indikera att en rad i den aktuella raduppsättningen bör ignoreras vid en bulkuppdatering. För mer information, se "Status and Operation Arrays" senare i denna funktionsreferens.
SQL_DELETE Drivrutinen placerar markören på raden som anges av RowNumber och tar bort den underliggande dataraden. Den ändrar motsvarande element i radstatusarrayen till SQL_ROW_DELETED. Efter att raden har raderats är följande inte giltiga för raden: positionerade uppdaterings- och borttagningssatser, anrop till SQLGetData och anrop till SQLSetPos med Operation satt till något annat än SQL_POSITION. För drivrutiner som stödjer packning tas raden bort från markören när ny data hämtas från datakällan.

Om raden förblir synlig beror på markörtypen. Till exempel är raderade rader synliga för statiska och tangentstyrningsstyrda markörer men osynliga för dynamiska markörer.

Raden operationsarrayen som pekas på av attributet SQL_ATTR_ROW_OPERATION_PTR statement kan användas för att indikera att en rad i den aktuella raduppsättningen ska ignoreras vid en bulkborttagning. För mer information, se "Status and Operation Arrays" senare i denna funktionsreferens.

LockType-argumentet

LockType-argumentet ger applikationer ett sätt att kontrollera samtidighet. I de flesta fall kommer datakällor som stödjer samtidighetsnivåer och transaktioner endast att stödja det SQL_LOCK_NO_CHANGE värdet av LockType-argumentet . LockType-argumentet används generellt endast för filbaserat stöd.

Argumentet LockType specificerar radens låsstatus efter att SQLSetPos har exekverats. Om drivrutinen inte kan låsa raden vare sig för att utföra den begärda operationen eller för att uppfylla LockType-argumentet , returnerar den SQL_ERROR och SQLSTATE 42000 (Syntaxfel eller åtkomstbrott).

Även om LockType-argumentet specificeras för ett enda uttalande, ger låset samma privilegier till alla satser på anslutningen. I synnerhet kan ett lås som erhålls av ett uttalande på en anslutning låsas upp av ett annat uttalande på samma anslutning.

En rad låst via SQLSetPos förblir låst tills applikationen anropar SQLSetPos för raden med LockType satt till SQL_LOCK_UNLOCK, eller tills applikationen anropar SQLFreeHandle för satsen eller SQLFreeStmt med SQL_CLOSE-alternativet. För en drivrutin som stödjer transaktioner låses en rad låst via SQLSetPos när applikationen anropar SQLEndTran för att committa eller rulla tillbaka en transaktion på anslutningen (om en markör stängs när en transaktion committas eller rullas tillbaka, vilket indikeras av de SQL_CURSOR_COMMIT_BEHAVIOR och SQL_CURSOR_ROLLBACK_BEHAVIOR informationstyper som returneras av SQLGetInfo).

LockType-argumentet stöder följande typer av lås. För att avgöra vilka lås som stöds av en datakälla anropar en applikation SQLGetInfo med informationstypen SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 eller SQL_STATIC_CURSOR_ATTRIBUTES1 (beroende på markörens typ).

LockType-argumentet Låstyp
SQL_LOCK_NO_CHANGE Drivrutinen eller datakällan säkerställer att raden är i samma låsta eller olåsta tillstånd som innan SQLSetPos anropades . Detta värde av LockType tillåter datakällor som inte stöder explicit radnivålåsning att använda den låsning som krävs av nuvarande samtidighets- och transaktionsisoleringsnivåer.
SQL_LOCK_EXCLUSIVE Drivrutinen eller datakällan låser raden exklusivt. Ett uttalande på en annan anslutning eller i en annan applikation kan inte användas för att få några lås på raden.
SQL_LOCK_UNLOCK Drivrutinen eller datakällan låser upp raden.

Om en drivrutin stödjer SQL_LOCK_EXCLUSIVE men inte stöder SQL_LOCK_UNLOCK, kommer en rad som är låst att förbli låst tills ett av funktionsanropen som beskrivs i föregående stycke sker.

Om en drivrutin stöder SQL_LOCK_EXCLUSIVE men inte SQL_LOCK_UNLOCK, kommer en rad som är låst att förbli låst tills applikationen anropar SQLFreeHandle för satsen eller SQLFreeStmt med SQL_CLOSE-alternativet. Om drivrutinen stödjer transaktioner och stänger markören vid committing eller rollning av transaktionen, anropar applikationen SQLEndTran.

För uppdaterings- och borttagningsoperationerna i SQLSetPos använder applikationen argumentet LockType enligt följande:

  • För att garantera att en rad inte ändras efter att den hämtats, anropar en applikation SQLSetPos med Operation satt till SQL_REFRESH och LockType satt till SQL_LOCK_EXCLUSIVE.

  • Om applikationen sätter LockType till SQL_LOCK_NO_CHANGE garanterar drivrutinen att en uppdaterings- eller borttagningsoperation endast lyckas om applikationen specificerat SQL_CONCUR_LOCK för attributet SQL_ATTR_CONCURRENCY-satsen.

  • Om applikationen specificerar SQL_CONCUR_ROWVER eller SQL_CONCUR_VALUES för attributet SQL_ATTR_CONCURRENCY satsen, jämför drivrutinen radversioner eller värden och avvisar operationen om raden har ändrats sedan applikationen hämtade raden.

  • Om applikationen anger SQL_CONCUR_READ_ONLY för attributet SQL_ATTR_CONCURRENCY statement, avvisar drivrutinen alla uppdaterings- eller borttagningsoperationer.

För mer information om attributet SQL_ATTR_CONCURRENCY sats, se SQLSetStmtAttr.

Status och Operation Arrays

Följande status- och operationsarrayer används vid anrop av SQLSetPos:

  • Radstatusarrayen (som pekas på av fältet SQL_DESC_ARRAY_STATUS_PTR i IRD och attributet SQL_ATTR_ROW_STATUS_ARRAY) innehåller statusvärden för varje datarad i raduppsättningen. Drivrutinen sätter statusvärdena i denna array efter ett anrop till SQLFetch, SQLFetchScroll, SQLBulkOperations eller SQLSetPos. Denna array pekas på av attributet SQL_ATTR_ROW_STATUS_PTR statement.

  • Radoperationsarrayen (som pekas på av SQL_DESC_ARRAY_STATUS_PTR-fältet i ARD och attributet SQL_ATTR_ROW_OPERATION_ARRAY-satsen) innehåller ett värde för varje rad i radmängden som anger om ett anrop till SQLSetPos för en bulkoperation ignoreras eller utförs. Varje element i matrisen är inställt på antingen SQL_ROW_PROCEED (standard) eller SQL_ROW_IGNORE. Denna array pekas på av attributet SQL_ATTR_ROW_OPERATION_PTR statement.

Antalet element i status- och operationsarrayerna måste motsvara antalet rader i radmängden (enligt attributet SQL_ATTR_ROW_ARRAY_SIZE statement).

För information om radstatusarrayen, se SQLFetch. För information om radoperationsmatrisen, se "Ignorering a Row in a Bulk Operation" senare i detta avsnitt.

Användning av SQLSetPos

Innan en applikation anropar SQLSetPos måste den utföra följande sekvens av steg:

  1. Om applikationen anropar SQLSetPos med Operation satt till SQL_UPDATE, anropa SQLBindCol (eller SQLSetDescRec) för varje kolumn för att specificera dess datatyp och binda buffertar för kolumnens data och längd.

  2. Om applikationen anropar SQLSetPos med Operation satt till SQL_DELETE eller SQL_UPDATE, anropa SQLColAttribute för att säkerställa att kolumnerna som ska tas bort eller uppdateras är uppdaterabara.

  3. Anropa SQLExecDirect, SQLExecute eller en katalogfunktion för att skapa en resultatuppsättning.

  4. Anropa SQLFetch eller SQLFetchScroll för att hämta datan.

För mer information om att använda SQLSetPos, se Uppdatera data med SQLSetPos.

Radera data med SQLSetPos

För att radera data med SQLSetPos anropar en applikation SQLSetPos med RowNumber satt till radnumret som ska tas bort och Operation inställt på SQL_DELETE.

Efter att datan har raderats ändrar drivrutinen värdet i implementationens radstatusarray för rätt rad för att SQL_ROW_DELETED (eller SQL_ROW_ERROR).

Uppdatering av data med SQLSetPos

En applikation kan skicka värdet för en kolumn antingen i den bundna databufferten eller med ett eller flera anrop till SQLPutData. Kolumner vars data skickas med SQLPutData kallas data-at-exekvering-kolumner. Dessa används ofta för att skicka data för SQL_LONGVARBINARY och SQL_LONGVARCHAR kolumner och kan blandas med andra kolumner.

För att uppdatera data med SQLSetPos, en applikation:

  1. Placerar värden i data- och längd-/indikatorbuffertar bundna med SQLBindCol:

    • För normala kolumner placerar applikationen det nya kolumnvärdet i *TargetValuePtr-bufferten och längden på det värdet i *StrLen_or_IndPtr-bufferten . Om raden inte bör uppdateras placerar applikationen SQL_ROW_IGNORE i radens element i radoperationsarrayen.

    • För data-at-exekvering-kolumner placerar applikationen ett applikationsdefinierat värde, såsom kolumnnumret, i *TargetValuePtr-bufferten . Värdet kan användas senare för att identifiera kolumnen.

      Applikationen placerar resultatet av makrot SQL_LEN_DATA_AT_EXEC(längd) i bufferten *StrLen_or_IndPtr . Om SQL-datatypen i kolumnen är SQL_LONGVARBINARY, SQL_LONGVARCHAR eller en lång datakällasspecifik datatyp och drivrutinen returnerar "Y" för den SQL_NEED_LONG_DATA_LEN informationstypen i SQLGetInfo, är längden antalet byte data som ska skickas för parametern; annars måste det vara ett icke-negativt värde och ignoreras.

  2. Anropar SQLSetPos med argumentet Operation satt till SQL_UPDATE för att uppdatera dataraden.

    • Om det inte finns några data-at-exekveringskolumner är processen slutförd.

    • Om det finns några kolumner för data vid exekvering returnerar funktionen SQL_NEED_DATA och går vidare till steg 3.

  3. Anropar SQLParamData för att hämta adressen till *TargetValuePtr-bufferten för den första data-at-exekveringskolumnen som ska bearbetas. SQLParamData returnerar SQL_NEED_DATA. Applikationen hämtar det applikationsdefinierade värdet från *TargetValuePtr-bufferten .

    Anmärkning

    Även om data-at-exekveringsparametrar liknar data-at-exekvering-kolumner, är värdet som returneras av SQLParamData olika för varje.

    Anmärkning

    Data-at-exekvering-parametrar är parametrar i en SQL-sats för vilka data skickas med SQLPutData när satsen exekveras med SQLExecDirect eller SQLExecute. De är bundna med SQLBindParameter eller genom att sätta deskriptorer med SQLSetDescRec. Värdet som returneras av SQLParamData är ett 32-bitars värde som skickas till SQLBindParameter i argumentet ParameterValuePtr .

    Anmärkning

    Data-at-exekveringskolumner är kolumner i en raduppsättning för vilka data skickas med SQLPutData när en rad uppdateras med SQLSetPos. De är bundna till SQLBindCol. Värdet som returneras av SQLParamData är adressen till raden i *TargetValuePtr-bufferten som bearbetas.

  4. Anropar SQLPutData en eller flera gånger för att skicka data för kolumnen. Mer än ett anrop behövs om alla datavärden inte kan returneras i *TargetValuePtr-bufferten specificerad i SQLPutData; flera anrop till SQLPutData för samma kolumn är endast tillåtna när tecken C-data skickas till en kolumn med en tecken-, binär- eller datakällspecifik datatyp eller när binär C-data skickas till en kolumn med tecken-, binär- eller datakällsspecifik datatyp.

  5. Anropar SQLParamData igen för att signalera att all data har skickats för kolumnen.

    • Om det finns fler data-at-exekvering-kolumner returnerar SQLParamData SQL_NEED_DATA och adressen till TargetValuePtr-bufferten för nästa data-at-exekvering-kolumn som ska bearbetas. Applikationen upprepar steg 4 och 5.

    • Om det inte finns några fler kolumner för data vid exekvering är processen slutförd. Om satsen kördes framgångsrikt returnerar SQLParamData SQL_SUCCESS eller SQL_SUCCESS_WITH_INFO; Om utförandet misslyckades returnerar den SQL_ERROR. Vid denna punkt kan SQLParamData returnera vilket SQLSTATE som helst som kan returneras av SQLSetPos.

Om data har uppdaterats ändrar drivrutinen värdet i implementationens radstatusarray för att lämplig rad ska SQL_ROW_UPDATED.

Om operationen avbryts eller ett fel uppstår i SQLParamData eller SQLPutData, kan applikationen efter att SQLSetPos returnerat SQL_NEED_DATA och innan data har skickats för alla data-at-exekveringskolumner endast anropa SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions,SQLParamData eller SQLPutData för satsen eller anslutningen som är kopplad till satsen. Om den anropar någon annan funktion för satsen eller kopplingen som är kopplad till satsen, returnerar funktionen SQL_ERROR och SQLSTATE HY010 (Funktionssekvensfel).

Om applikationen anropar SQLCancel medan drivrutinen fortfarande behöver data för data-at-exekvering-kolumner, avbryter drivrutinen operationen. Applikationen kan sedan anropa SQLSetPos igen; Avbrytning påverkar inte markörens tillstånd eller den aktuella markörpositionen.

När SELECT-listan i frågespecifikationen kopplad till markören innehåller mer än en referens till samma kolumn, är det drivrutinsdefinierad om ett fel genereras eller om drivrutinen ignorerar de duplicerade referenserna och utför de begärda operationerna.

Utförande av bulkoperationer

Om RowNumber-argumentet är 0 utför drivrutinen den operation som anges i Operation-argumentet för varje rad i radmängden som har värdet SQL_ROW_PROCEED i sitt fält i radoperationsarrayen som pekas på av SQL_ATTR_ROW_OPERATION_PTR satsattributet. Detta är ett giltigt värde för RowNumber-argumentet för ett Operation-argument SQL_DELETE, SQL_REFRESH eller SQL_UPDATE, men inte SQL_POSITION. SQLSetPos med en operation på SQL_POSITION och ett radnummer lika med 0 kommer att returnera SQLSTATE HY109 (ogiltig markörposition).

Om ett fel uppstår som rör hela raduppsättningen, såsom SQLSTATE HYT00 (Timeout expired), returnerar drivrutinen SQL_ERROR och relevant SQLSTATE. Innehållet i raduppsättningsbuffertarna är odefinierat och markörpositionen är oförändrad.

Om ett fel uppstår som rör en enda rad, följer drivrutinen:

  • Sätter elementet för raden i radstatusarrayen som pekas på av attributet SQL_ATTR_ROW_STATUS_PTR statement till SQL_ROW_ERROR.

  • Postar en eller flera ytterligare SQLSTATE för felet i felkön och sätter fältet SQL_DIAG_ROW_NUMBER i diagnosdatastrukturen.

Efter att den har bearbetat felet eller varningen, om drivrutinen slutför operationen för de återstående raderna i raduppsättningen, returnerar den SQL_SUCCESS_WITH_INFO. Alltså innehåller felkön noll eller fler ytterligare SQLSTATES för varje rad som returnerade ett fel. Om drivrutinen stoppar operationen efter att felet eller varningen har behandlats, återvänder den SQL_ERROR.

Om drivrutinen returnerar några varningar, såsom SQLSTATE 01004 (Data trunkerad), returnerar den varningar som gäller för hela raduppsättningen eller för okända rader i raduppsättningen innan den returnerar felinformationen som gäller för specifika rader. Den returnerar varningar för specifika rader tillsammans med annan felinformation om dessa rader.

Om RowNumber är lika med 0 och Operation är SQL_UPDATE, SQL_REFRESH eller SQL_DELETE, pekas antalet rader som SQLSetPos arbetar på av attributet SQL_ATTR_ROWS_FETCHED_PTR.

Om RowNumber är lika med 0 och Operation är SQL_DELETE, SQL_REFRESH eller SQL_UPDATE, är den aktuella raden efter operationen densamma som raden före operationen.

Ignorera en rad i en bulkoperation

Radoperationsarrayen kan användas för att ange att en rad i den aktuella raduppsättningen ska ignoreras under en bulkoperation med SQLSetPos. För att styra drivrutinen att ignorera en eller flera rader under en bulkoperation bör en applikation utföra följande steg:

  1. Anropa SQLSetStmtAttr för att sätta attributet SQL_ATTR_ROW_OPERATION_PTR statement att peka på en array av SQLUSMALLINTs. Detta fält kan också sättas genom att anropa SQLSetDescField för att sätta det SQL_DESC_ARRAY_STATUS_PTR huvudfältet i ARD, vilket kräver att en applikation får tag på deskriptorhandtaget.

  2. Sätt varje element i radoperationsmatrisen till ett av två värden:

    • SQL_ROW_IGNORE, för att indikera att raden utesluts för bulkoperationen.

    • SQL_ROW_PROCEED, för att indikera att raden ingår i bulkoperationen. (Det här är standardvärdet.)

  3. Anropa SQLSetPos för att utföra bulkoperationen.

Följande regler gäller för radoperationsarrayen:

  • SQL_ROW_IGNORE och SQL_ROW_PROCEED påverkar endast bulkoperationer med SQLSetPos med en operation SQL_DELETE eller SQL_UPDATE. De påverkar inte anrop till SQLSetPos med en operation av SQL_REFRESH eller SQL_POSITION.

  • Pekaren är inställd på null som standard.

  • Om pekaren är null uppdateras alla rader som om alla element sattes till SQL_ROW_PROCEED.

  • Att sätta ett element till SQL_ROW_PROCEED garanterar inte att operationen sker på just den raden. Till exempel, om en viss rad i raduppsättningen har status SQL_ROW_ERROR, kan drivrutinen kanske inte uppdatera den raden oavsett om applikationen specificerat SQL_ROW_PROCEED. En applikation måste alltid kontrollera radstatusarrayen för att se om operationen lyckades.

  • SQL_ROW_PROCEED definieras som 0 i headerfilen. En applikation kan initialisera radoperationsarrayen till 0 för att bearbeta alla rader.

  • Om elementnummer "n" i radoperationsarrayen sätts till SQL_ROW_IGNORE och SQLSetPos anropas för att utföra en bulkuppdatering eller borttagning, förblir den n:te raden i raduppsättningen oförändrad efter anropet till SQLSetPos.

  • Ett program bör automatiskt ställa in en skrivskyddad kolumn till SQL_ROW_IGNORE.

Ignorera en kolumn i en bulkoperation

För att undvika onödig bearbetningsdiagnostik som genereras av försök till uppdateringar av en eller flera skrivskyddade kolumner kan en applikation ställa in värdet i boundlängden/indikatorbufferten till SQL_COLUMN_IGNORE. För mer information, se SQLBindCol.

Kodexempel

I följande exempel tillåter en applikation en användare att bläddra i ORDERS-tabellen och uppdatera orderstatus. Markören är keyset-driven med en raduppsättningsstorlek på 20 och använder optimistisk samtidighetskontroll för att jämföra radversioner. Efter att varje raduppsättning hämtats skriver applikationen ut den och låter användaren välja och uppdatera statusen för en beställning. Applikationen använder SQLSetPos för att placera markören på den valda raden och utför en positionerad uppdatering av raden. (Felhantering utelämnas för tydlighetens skull.)

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

För fler exempel, se Positioned Update and Delete-satser och Updating Rows in the Rowset med SQLSetPos.

Mer information om Se
Binda en buffert till en kolumn i en resultatuppsättning SQLBindCol-funktion
Utför bulkoperationer som inte rör blockmarkörens position SQLBulkOperations-funktionen
Avbryta instruktionsbearbetning SQLCancel-funktion
Hämtar ett datablock eller bläddrar igenom en resultatuppsättning SQLFetchScroll-funktion
Att få ett enda fält av en beskrivare SQLGetDescField-funktionen
Att få flera fält av en beskrivare SQLGetDescRec-funktionen
Att sätta ett enskilt fält av en beskrivare SQLSetDescField-funktionen
Att sätta flera fält av en beskrivare SQLSetDescRec-funktionen
Ange ett instruktionsattribut SQLSetStmtAttr-funktion