SQLBulkOperations-funktion

Överensstämmelse
Version introducerad: ODBC 3.0 Standardsefterlevnad: ODBC

Summary
SQLBulkOperations utför bulkinsättningar och bulk-bokmärkesoperationer, inklusive uppdatering, borttagning och hämtning efter bokmärke.

Syntax

  
SQLRETURN SQLBulkOperations(  
     SQLHSTMT       StatementHandle,  
     SQLUSMALLINT   Operation);  

Arguments

StatementHandle
[Indata] Instruktionshandtag.

Operation
[Input] Operation att utföra:

SQL_ADD SQL_UPDATE_BY_BOOKMARK SQL_DELETE_BY_BOOKMARK SQL_FETCH_BY_BOOKMARK

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 SQLBulkOperations 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 SQLBulkOperations och förklarar varje sådant 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 Beskrivning
01000 Allmän varning Informationsmeddelande för drivrutinsspecifikt. (Funktionen returnerar SQL_SUCCESS_WITH_INFO.)
01004 Högeravskärning av strängdata Operation-argumentet var SQL_FETCH_BY_BOOKMARK, och sträng- eller binärdata returnerades för en kolumn eller kolumner med datatypen SQL_C_CHAR eller SQL_C_BINARY resulterade i trunkering av icke-blanka tecken eller icke-NULL-binärdata.
01S01 Fel i rad Operation-argumentet var SQL_ADD, och ett fel uppstod i en eller flera rader under operationen men minst en rad lades till framgångsrikt. (Funktionen returnerar SQL_SUCCESS_WITH_INFO.)

(Detta fel uppstår endast när en applikation arbetar med en ODBC 2. X-drivrutin .)
01S07 Fraktionell trunkering Operation-argumentet var SQL_FETCH_BY_BOOKMARK, datatypen i applikationsbufferten var inte SQL_C_CHAR eller SQL_C_BINARY, och datan som returnerades till applikationsbuffertar för en eller flera kolumner var avkortad. (För numeriska C-datatyper avkortades den bråkdelade delen av talet. För tids-, tidsstämpel- och intervalldatatyper C 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 Operation-argumentet var SQL_FETCH_BY_BOOKMARK, och datavärdet för en kolumn i resultatuppsättningen kunde inte konverteras till den datatyp som specificerades av TargetType-argumentet i anropet till SQLBindCol.

Operation-argumentet var SQL_UPDATE_BY_BOOKMARK eller SQL_ADD, och datavärdet i applikationsbuffertarna kunde inte konverteras till datatypen för en kolumn i resultatuppsättningen.
07009 Ogiltigt deskriptorindex Argumentet Operation var SQL_ADD, 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_BY_BOOKMARK; och inga kolumner kunde uppdateras eftersom alla kolumner antingen var obundna eller skrivskyddade, eller värdet i boundlängds-/indikatorbufferten var SQL_COLUMN_IGNORE.
22001 Högeravskärning av strängdata Tilldelningen av ett tecken eller binärt värde till en kolumn i resultatuppsättningen resulterade i trunkering av icke-blanka (för tecken) eller icke-null (för binära) tecken eller bytes.
22003 Numeriskt värde som ligger utom intervallet Operation-argumentet var SQL_ADD eller SQL_UPDATE_BY_BOOKMARK, och tilldelningen av ett numeriskt värde till en kolumn i resultatmängden gjorde att hela (till skillnad från bråkdelad) delen av talet avkortades.

Argumentet Operation var SQL_FETCH_BY_BOOKMARK, 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 Operation-argumentet var SQL_ADD eller SQL_UPDATE_BY_BOOKMARK, 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 hamnade utanför intervallet.

Argumentet Operation var SQL_FETCH_BY_BOOKMARK, och att returnera datum- eller tidsstämpelvärdet för en eller flera bundna kolumner skulle ha gjort att år-, månads- eller dagfältet hamnade utanför intervallet.
22008 Datum/tid-fältöverflöd Operation-argumentet var SQL_ADD eller SQL_UPDATE_BY_BOOKMARK, och prestandan av datumtidsaritmetik på data som skickades till en kolumn i resultatuppsättningen resulterade i att ett datumtidsfält (år, månad, dag, timme, minut eller andra fä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_FETCH_BY_BOOKMARK, och prestandan av datumtidsaritmetik på data som hämtades från resultatmängden resulterade i att ett datumtidsfä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 datumtider.
22015 Intervallfältsspill Operation-argumentet var SQL_ADD eller SQL_UPDATE_BY_BOOKMARK, och tilldelningen av en exakt numerisk eller intervall C-typ till en intervall-SQL-datatyp orsakade en förlust av betydande siffror.

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

Operation-argumentet var SQL_FETCH_BY_BOOKMARK, 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_FETCH_BY_BOOKMARK; 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_FETCH_BY_BOOKMARK; 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_ADD eller SQL_UPDATE_BY_BOOKMARK; 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 Operation-argumentet var SQL_ADD, SQL_DELETE_BY_BOOKMARK eller SQL_UPDATE_BY_BOOKMARK, och en integritetsbegränsning bröts.

Operation-argumentet var SQL_ADD, och en kolumn som inte var bunden definieras som INTE NULL och har ingen standard.

Operation-argumentet var SQL_ADD, längden som angavs i den begränsade bufferten StrLen_or_IndPtr var SQL_COLUMN_IGNORE, och kolumnen hade inget standardvärde.
24000 Ogiltigt markörtillstånd StatementHandle var i ett exekverat tillstånd, men ingen resultatuppsättning var kopplad till StatementHandle.
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 operationen som begärdes i Operation-argumentet.
44000 MED KONTROLLALTERNATIVsöverträdelse Operation-argumentet var SQL_ADD eller SQL_UPDATE_BY_BOOKMARK, och insättningen eller 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, på ett sådant sätt att en eller flera rader som påverkas av insättningen eller 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 körningen slutfördes anropades SQLCancel eller SQLCancelHandleStatementHandle. 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 SQLBulkOperations-funktionen anropades.

(DM) SQLExecute, SQLExecDirect eller SQLMoreResults anropades för StatementHandle och returnerades SQL_PARAM_DATA_AVAILABLE. Den här funktionen anropades innan data hämtades för alla strömmade parametrar.

(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 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) Föraren var en ODBC 2. x-drivrutin , och SQLBulkOperations anropades för ett StatementHandle innan SQLFetchScroll eller SQLFetch anropades.

(DM) SQLBulkOperations anropades efter att SQLExtendedFetch anropats på StatementHandle.
HY011 Attributet kan inte sättas nu (DM) Föraren var en ODBC 2. x-drivrutin , och attributet SQL_ATTR_ROW_STATUS_PTR sats sattes mellan anrop till SQLFetch eller SQLFetchScroll och SQLBulkOperations.
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_ADD eller SQL_UPDATE_BY_BOOKMARK; 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".

Operation-argumentet var SQL_ADD, attributet SQL_ATTR_USE_BOOKMARK sattes till SQL_UB_VARIABLE, och kolumn 0 var bunden till en buffert vars längd inte var lika med den maximala längden för bokmärket för denna resultatuppsättning. (Denna längd finns tillgänglig i det SQL_DESC_OCTET_LENGTH fältet i IRD och kan erhållas genom att anropa SQLDescribeCol, SQLColAttribute eller SQLGetDescField.)
HY092 Ogiltig attributidentifierare (DM) Värdet som angavs för Operation-argumentet var ogiltigt.

Operation-argumentet var SQL_ADD, SQL_UPDATE_BY_BOOKMARK eller SQL_DELETE_BY_BOOKMARK, och attributet SQL_ATTR_CONCURRENCY satsen sattes till SQL_CONCUR_READ_ONLY.

Operation-argumentet var SQL_DELETE_BY_BOOKMARK, SQL_FETCH_BY_BOOKMARK eller SQL_UPDATE_BY_BOOKMARK, och bokmärkeskolumnen var inte bunden eller så var attributet SQL_ATTR_USE_BOOKMARKS statement satt till SQL_UB_OFF.
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 argumentet Operation .
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. Tidsavbrottsperioden sätts via SQLSetStmtAttr med ett attributargument 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

Caution

För information om vilka satser SQLBulkOperations kan anropas i och vad den måste göra för kompatibilitet med ODBC 2. x applikationer, se avsnittet Block Cursors, Scrollable Cursors och Bakåtkompatibilitet i Appendix G: Drivrutinsriktlinjer för bakåtkompatibilitet.

En applikation använder SQLBulkOperations för att utföra följande operationer på bastabellen eller vyn som motsvarar den aktuella frågan:

  • Lägg till nya varv.

  • Uppdatera en uppsättning rader där varje rad identifieras av ett bokmärke.

  • Ta bort en uppsättning rader där varje rad identifieras med ett bokmärke.

  • Hämta en uppsättning rader där varje rad identifieras med ett bokmärke.

Efter ett anrop till SQLBulkOperations är blockmarkörens position odefinierad. Applikationen måste anropa SQLFetchScroll för att sätta markörens position. En applikation bör endast anropa SQLFetchScroll med ett FetchOrientation-argument SQL_FETCH_FIRST, SQL_FETCH_LAST, SQL_FETCH_ABSOLUTE eller SQL_FETCH_BOOKMARK. Markörpositionen är odefinierad om applikationen anropar SQLFetch eller SQLFetchScroll med ett FetchOrientation-argument SQL_FETCH_PRIOR, SQL_FETCH_NEXT eller SQL_FETCH_RELATIVE.

En kolumn kan ignoreras i bulkoperationer som utförs av ett anrop till SQLBulkOperations genom att ställa in kolumnlängden/indikatorbufferten som anges i anropet till SQLBindCol till SQL_COLUMN_IGNORE.

Det är inte nödvändigt för applikationen att sätta attributet SQL_ATTR_ROW_OPERATION_PTR statement när den anropar SQLBulkOperations eftersom rader inte kan ignoreras vid massoperationer med denna funktion.

Bufferten som pekas på av attributet SQL_ATTR_ROWS_FETCHED_PTR innehåller antalet rader som påverkas av ett anrop till SQLBulkOperations.

När Operation-argumentet är SQL_ADD eller SQL_UPDATE_BY_BOOKMARK och select-listan för frågespecifikationen kopplad till markören innehåller mer än en referens till samma kolumn, är det drivrutinsdefinierat om ett fel genereras eller om drivrutinen ignorerar de duplicerade referenserna och utför de begärda operationerna.

För mer information om hur man använder SQLBulkOperations, se Uppdatera data med SQLBulkOperations.

Utförande av bulkinsatser

För att infoga data med SQLBulkOperations utför en applikation följande sekvens av steg:

  1. Exekverar en fråga som returnerar en resultatuppsättning.

  2. Sätter attributet SQL_ATTR_ROW_ARRAY_SIZE statement till antalet rader som den vill infoga.

  3. Anropar SQLBindCol för att binda den data som den vill infoga. Datan är bunden till en array med en storlek lika med värdet SQL_ATTR_ROW_ARRAY_SIZE.

    Note

    Storleken på arrayen som pekas på av attributet SQL_ATTR_ROW_STATUS_PTR statement bör antingen vara lika med SQL_ATTR_ROW_ARRAY_SIZE eller SQL_ATTR_ROW_STATUS_PTR ska vara en nullpekare.

  4. Anropar SQLBulkOperations(StatementHandle, SQL_ADD) för att utföra insättningen.

  5. Om applikationen har satt attributet SQL_ATTR_ROW_STATUS_PTR statement kan den inspektera denna array för att se resultatet av operationen.

Om en applikation binder kolumn 0 innan den anropar SQLBulkOperations med ett Operation-argument SQL_ADD, kommer drivrutinen att uppdatera de bundna kolumnbuffertarna 0 med bokmärkesvärdena för den nyinsatta raden. För att detta ska ske måste applikationen ha satt attributet SQL_ATTR_USE_BOOKMARKS statement till SQL_UB_VARIABLE innan satsen exekveras. (Detta fungerar inte med en ODBC 2. X-drivrutin .)

Långa data kan läggas till i delar av SQLBulkOperations, genom att använda anrop till SQLParamData och SQLPutData. För mer information, se "Providing Long Data for Bulk Inserts and Updates" senare i denna funktionsreferens.

Det är inte nödvändigt för applikationen att anropa SQLFetch eller SQLFetchScroll innan den anropar SQLBulkOperations (förutom när den går mot en ODBC 2).x-förare ; se Bakåtkompatibilitet och standardöverensstämmelse).

Beteendet är drivrutinsdefinierat om SQLBulkOperations, med ett Operation-argument SQL_ADD, anropas på en markör som innehåller dubblettkolumner. Drivrutinen kan returnera ett drivrutinsdefinierat SQLSTATE, lägga till data i den första kolumnen som visas i resultatuppsättningen, eller utföra annat drivrutinsdefinierade beteende.

Utför massuppdateringar genom att använda bokmärken

För att utföra bulkuppdateringar genom att använda bokmärken med SQLBulkOperations utför en applikation följande steg i följd:

  1. Sätter attributet SQL_ATTR_USE_BOOKMARKS statement till SQL_UB_VARIABLE.

  2. Exekverar en fråga som returnerar en resultatuppsättning.

  3. Sätter attributet SQL_ATTR_ROW_ARRAY_SIZE statement till antalet rader som den vill uppdatera.

  4. Anropar SQLBindCol för att binda den data som den vill uppdatera. Datan är bunden till en array med en storlek lika med värdet SQL_ATTR_ROW_ARRAY_SIZE. Den anropar också SQLBindCol för att binda kolumn 0 (bokmärkeskolumnen).

  5. Kopierar bokmärkena för rader som den är intresserad av att uppdatera till arrayen bunden till kolumn 0.

  6. Uppdaterar datan i bound-buffertarna.

    Note

    Storleken på arrayen som pekas på av attributet SQL_ATTR_ROW_STATUS_PTR sats bör vara lika med SQL_ATTR_ROW_ARRAY_SIZE eller SQL_ATTR_ROW_STATUS_PTR bör vara en nullpekare.

  7. anropar SQLBulkOperations(StatementHandle, SQL_UPDATE_BY_BOOKMARK).

    Note

    Om applikationen har satt attributet SQL_ATTR_ROW_STATUS_PTR statement kan den inspektera denna array för att se resultatet av operationen.

  8. Anropar valfritt SQLBulkOperations(StatementHandle, SQL_FETCH_BY_BOOKMARK) för att hämta data till de bundna applikationsbuffertarna för att verifiera att uppdateringen har skett.

  9. Om data har uppdaterats ändrar drivrutinen värdet i radstatusarrayen för de lämpliga raderna att SQL_ROW_UPDATED.

Bulkuppdateringar utförda av SQLBulkOperations kan inkludera långa data genom att använda anrop till SQLParamData och SQLPutData. För mer information, se "Providing Long Data for Bulk Inserts and Updates" senare i denna funktionsreferens.

Om bokmärken finns kvar över markörer behöver applikationen inte anropa SQLFetch eller SQLFetchScroll innan den uppdateras med bokmärken. Den kan använda bokmärken som den har lagrat från en tidigare markör. Om bokmärken inte finns kvar över markörerna måste applikationen anropa SQLFetch eller SQLFetchScroll för att hämta bokmärkena.

Beteendet är drivrutinsdefinierad om SQLBulkOperations, med ett Operation-argument SQL_UPDATE_BY_BOOKMARK, anropas på en markör som innehåller dubblettkolumner. Drivrutinen kan returnera en drivrutinsdefinierad SQLSTATE, uppdatera den första kolumnen som visas i resultatuppsättningen eller utföra annat drivrutinsdefinierade beteende.

Utför bulkhämtningar med hjälp av bokmärken

För att utföra masshämtningar med bokmärken med SQLBulkOperations utför en applikation följande steg i följd:

  1. Sätter attributet SQL_ATTR_USE_BOOKMARKS statement till SQL_UB_VARIABLE.

  2. Exekverar en fråga som returnerar en resultatuppsättning.

  3. Sätter attributet SQL_ATTR_ROW_ARRAY_SIZE till antalet rader som den vill hämta.

  4. Anropar SQLBindCol för att binda den data som den vill hämta. Datan är bunden till en array med en storlek lika med värdet SQL_ATTR_ROW_ARRAY_SIZE. Den anropar också SQLBindCol för att binda kolumn 0 (bokmärkeskolumnen).

  5. Kopierar bokmärkena för rader som den är intresserad av att hämta till arrayen som är bunden till kolumn 0. (Detta förutsätter att applikationen redan har hämtat bokmärken separat.)

    Note

    Storleken på arrayen som pekas på av attributet SQL_ATTR_ROW_STATUS_PTR sats bör vara lika med SQL_ATTR_ROW_ARRAY_SIZE eller SQL_ATTR_ROW_STATUS_PTR bör vara en nullpekare.

  6. anropar SQLBulkOperations(StatementHandle, SQL_FETCH_BY_BOOKMARK).

  7. Om applikationen har satt attributet SQL_ATTR_ROW_STATUS_PTR statement kan den inspektera denna array för att se resultatet av operationen.

Om bokmärken kvarstår över markörer behöver applikationen inte anropa SQLFetch eller SQLFetchScroll innan bokmärken hämtas. Den kan använda bokmärken som den har lagrat från en tidigare markör. Om bokmärken inte finns kvar över markörerna måste applikationen anropa SQLFetch eller SQLFetchScroll en gång för att hämta bokmärkena.

Utföra massborttagningar med bokmärken

För att utföra massborttagningar med bokmärken i SQLBulkOperations utför en applikation följande steg i följd:

  1. Sätter attributet SQL_ATTR_USE_BOOKMARKS statement till SQL_UB_VARIABLE.

  2. Exekverar en fråga som returnerar en resultatuppsättning.

  3. Sätter attributet SQL_ATTR_ROW_ARRAY_SIZE till antalet rader som den vill ta bort.

  4. Anropar SQLBindCol för att binda kolumn 0 (bokmärkeskolumnen).

  5. Kopierar bokmärkena för rader som den är intresserad av att ta bort till arrayen som är bunden till kolumn 0.

    Note

    Storleken på arrayen som pekas på av attributet SQL_ATTR_ROW_STATUS_PTR sats bör vara lika med SQL_ATTR_ROW_ARRAY_SIZE eller SQL_ATTR_ROW_STATUS_PTR bör vara en nullpekare.

  6. anropar SQLBulkOperations(StatementHandle, SQL_DELETE_BY_BOOKMARK).

  7. Om applikationen har satt attributet SQL_ATTR_ROW_STATUS_PTR statement kan den inspektera denna array för att se resultatet av operationen.

Om bokmärken kvarstår över markörer behöver applikationen inte anropa SQLFetch eller SQLFetchScroll innan bokmärken tas bort. Den kan använda bokmärken som den har lagrat från en tidigare markör. Om bokmärken inte finns kvar över markörerna måste applikationen anropa SQLFetch eller SQLFetchScroll en gång för att hämta bokmärkena.

Tillhandahåller långa data för bulkinsättningar och uppdateringar

Lång data kan tillhandahållas för bulkinsättningar och uppdateringar som utförs av anrop till SQLBulkOperations. För att infoga eller uppdatera långa data utför en applikation följande steg utöver de steg som beskrivs i avsnitten "Utför bulkinsättningar" och "Utför bulkuppdateringar med bokmärken" tidigare i detta ämne.

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

    Applikationen placerar resultatet av makron 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. När SQLBulkOperations anropas, om det finns data-at-exekvering-kolumner, returnerar funktionen SQL_NEED_DATA och går vidare till steg 3, som följer. (Om det inte finns några kolumner för data vid exekvering är processen slutförd.)

  3. Applikationen 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 .

    Note

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

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

  4. Applikationen 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. Applikationen 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 vilken SQLSTATE som helst som kan returneras av SQLBulkOperations.

Om operationen avbryts eller ett fel uppstår i SQLParamData eller SQLPutData efter att SQLBulkOperations returnerat SQL_NEED_DATA och innan data har skickats för alla data-at-exekveringskolumner, kan applikationen 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 SQLBulkOperations igen; Avbrytning påverkar inte markörens tillstånd eller den aktuella markörpositionen.

Radstatusmatris

Radstatusarrayen innehåller statusvärden för varje datarad i radmängden efter ett anrop till SQLBulkOperations. Drivrutinen sätter statusvärdena i denna array efter ett anrop till SQLFetch, SQLFetchScroll, SQLSetPos eller SQLBulkOperations. Denna array fylls initialt med ett anrop till SQLBulkOperations om SQLFetch eller SQLFetchScroll inte har anropats tidigare SQLBulkOperations. Denna array pekas på av attributet SQL_ATTR_ROW_STATUS_PTR statement. Antalet element i radstatusarrayerna måste motsvara antalet rader i raduppsättningen (som definierat av attributet SQL_ATTR_ROW_ARRAY_SIZE statement). För information om denna radstatusarray, se SQLFetch.

Kodexempel

Följande exempel hämtar 10 rader data åt gången från tabellen Kunder. Den uppmanar sedan användaren att utföra en åtgärd. För att minska nätverkstrafiken uppdateras, raderar och infogar exempelbufferten lokalt i de bundna arrayerna, men med offsets förbi raduppsättningsdatan. När användaren väljer att skicka uppdateringar, raderingar och insättningar till datakällan, sätter koden bindningsoffset på rätt sätt och anropar SQLBulkOperations. För enkelhetens skull kan användaren inte buffra mer än 10 uppdateringar, raderingar eller insättningar.

// SQLBulkOperations_Function.cpp  
// compile with: ODBC32.lib  
#include <windows.h>  
#include <sqlext.h>  
#include "stdio.h"  
  
#define UPDATE_ROW 100  
#define DELETE_ROW 101  
#define ADD_ROW 102  
#define SEND_TO_DATA_SOURCE 103  
#define UPDATE_OFFSET 10  
#define INSERT_OFFSET 20  
#define DELETE_OFFSET 30  
  
// Define structure for customer data (assume 10 byte maximum bookmark size).  
typedef struct tagCustStruct {  
   SQLCHAR Bookmark[10];  
   SQLINTEGER BookmarkLen;  
   SQLUINTEGER CustomerID;  
   SQLINTEGER CustIDInd;  
   SQLCHAR CompanyName[51];  
   SQLINTEGER NameLenOrInd;  
   SQLCHAR Address[51];  
   SQLINTEGER AddressLenOrInd;  
   SQLCHAR Phone[11];  
   SQLINTEGER PhoneLenOrInd;  
} CustStruct;  
  
// Allocate 40 of these structures. Elements 0-9 are for the current rowset,  
// elements 10-19 are for the buffered updates, elements 20-29 are for  
// the buffered inserts, and elements 30-39 are for the buffered deletes.  
CustStruct CustArray[40];  
SQLUSMALLINT RowStatusArray[10], Action, RowNum, NumUpdates = 0, NumInserts = 0,  
NumDeletes = 0;  
SQLLEN BindOffset = 0;  
SQLRETURN retcode;  
SQLHENV henv = NULL;  
SQLHDBC hdbc = NULL;  
SQLHSTMT hstmt = NULL;  
  
int main() {  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);   
   retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
   retcode = SQLConnect(hdbc, (SQLCHAR*) "Northwind", SQL_NTS, (SQLCHAR*) NULL, 0, NULL, 0);  
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);  
  
   // Set the following statement attributes:  
   // SQL_ATTR_CURSOR_TYPE:           Keyset-driven  
   // SQL_ATTR_ROW_BIND_TYPE:         Row-wise  
   // SQL_ATTR_ROW_ARRAY_SIZE:        10  
   // SQL_ATTR_USE_BOOKMARKS:         Use variable-length bookmarks  
   // SQL_ATTR_ROW_STATUS_PTR:        Points to RowStatusArray  
   // SQL_ATTR_ROW_BIND_OFFSET_PTR:   Points to BindOffset  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN, 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)sizeof(CustStruct), 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)10, 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_USE_BOOKMARKS, (SQLPOINTER)SQL_UB_VARIABLE, 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &BindOffset, 0);  
  
   // Bind arrays to the bookmark, CustomerID, CompanyName, Address, and Phone columns.  
   retcode = SQLBindCol(hstmt, 0, SQL_C_VARBOOKMARK, CustArray[0].Bookmark, sizeof(CustArray[0].Bookmark), &CustArray[0].BookmarkLen);  
   retcode = SQLBindCol(hstmt, 1, SQL_C_ULONG, &CustArray[0].CustomerID, 0, &CustArray[0].CustIDInd);  
   retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, CustArray[0].CompanyName, sizeof(CustArray[0].CompanyName), &CustArray[0].NameLenOrInd);  
   retcode = SQLBindCol(hstmt, 3, SQL_C_CHAR, CustArray[0].Address, sizeof(CustArray[0].Address), &CustArray[0].AddressLenOrInd);  
   retcode = SQLBindCol(hstmt, 4, SQL_C_CHAR, CustArray[0].Phone, sizeof(CustArray[0].Phone), &CustArray[0].PhoneLenOrInd);  
  
   // Execute a statement to retrieve rows from the Customers table.  
   retcode = SQLExecDirect(hstmt, (SQLCHAR*)"SELECT CustomerID, CompanyName, Address, Phone FROM Customers", SQL_NTS);  
  
   // Fetch and display the first 10 rows.  
   retcode = SQLFetchScroll(hstmt, SQL_FETCH_NEXT, 0);  
   // DisplayCustData(CustArray, 10);  
  
   // Call GetAction to get an action and a row number from the user.  
   // while (GetAction(&Action, &RowNum)) {  
   Action = SQL_FETCH_NEXT;  
   RowNum = 2;  
   switch (Action) {  
      case SQL_FETCH_NEXT:  
      case SQL_FETCH_PRIOR:  
      case SQL_FETCH_FIRST:  
      case SQL_FETCH_LAST:  
      case SQL_FETCH_ABSOLUTE:  
      case SQL_FETCH_RELATIVE:  
         // Fetch and display the requested data.  
         SQLFetchScroll(hstmt, Action, RowNum);  
         // DisplayCustData(CustArray, 10);  
         break;  
  
      case UPDATE_ROW:  
         // Check if we have reached the maximum number of buffered updates.  
         if (NumUpdates < 10) {  
            // Get the new customer data and place it in the next available element of  
            // the buffered updates section of CustArray, copy the bookmark of the row  
            // being updated to the same element, and increment the update counter.  
            // Checking to see we have not already buffered an update for this  
            // row not shown.  
            // GetNewCustData(CustArray, UPDATE_OFFSET + NumUpdates);  
            memcpy(CustArray[UPDATE_OFFSET + NumUpdates].Bookmark,  
               CustArray[RowNum - 1].Bookmark,  
               CustArray[RowNum - 1].BookmarkLen);  
            CustArray[UPDATE_OFFSET + NumUpdates].BookmarkLen =  
               CustArray[RowNum - 1].BookmarkLen;  
            NumUpdates++;  
         } else {  
            printf("Buffers full. Send buffered changes to the data source.");  
         }  
         break;  
      case DELETE_ROW:  
         // Check if we have reached the maximum number of buffered deletes.  
         if (NumDeletes < 10) {  
            // Copy the bookmark of the row being deleted to the next available element  
            // of the buffered deletes section of CustArray and increment the delete  
            // counter. Checking to see we have not already buffered an update for  
            // this row not shown.  
            memcpy(CustArray[DELETE_OFFSET + NumDeletes].Bookmark,  
               CustArray[RowNum - 1].Bookmark,  
               CustArray[RowNum - 1].BookmarkLen);  
  
            CustArray[DELETE_OFFSET + NumDeletes].BookmarkLen =  
               CustArray[RowNum - 1].BookmarkLen;  
  
            NumDeletes++;  
         } else  
            printf("Buffers full. Send buffered changes to the data source.");  
         break;  
  
      case ADD_ROW:  
         // reached maximum number of buffered inserts?  
         if (NumInserts < 10) {  
            // Get the new customer data and place it in the next available element of  
            // the buffered inserts section of CustArray and increment insert counter.  
            // GetNewCustData(CustArray, INSERT_OFFSET + NumInserts);  
            NumInserts++;  
         } else  
            printf("Buffers full. Send buffered changes to the data source.");  
         break;  
  
      case SEND_TO_DATA_SOURCE:  
         // If there are any buffered updates, inserts, or deletes, set the array size  
         // to that number, set the binding offset to use the data in the buffered  
         // update, insert, or delete part of CustArray, and call SQLBulkOperations to  
         // do the updates, inserts, or deletes. Because we will never have more than  
         // 10 updates, inserts, or deletes, we can use the same row status array.  
         if (NumUpdates) {  
            SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)NumUpdates, 0);  
            BindOffset = UPDATE_OFFSET * sizeof(CustStruct);  
            SQLBulkOperations(hstmt, SQL_UPDATE_BY_BOOKMARK);  
            NumUpdates = 0;  
         }  
  
         if (NumInserts) {  
            SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)NumInserts, 0);  
            BindOffset = INSERT_OFFSET * sizeof(CustStruct);  
            SQLBulkOperations(hstmt, SQL_ADD);  
            NumInserts = 0;  
         }  
  
         if (NumDeletes) {  
            SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)NumDeletes, 0);  
            BindOffset = DELETE_OFFSET * sizeof(CustStruct);  
            SQLBulkOperations(hstmt, SQL_DELETE_BY_BOOKMARK);  
            NumDeletes = 0;  
         }  
  
         // If there were any updates, inserts, or deletes, reset the binding offset  
         // and array size to their original values.  
         if (NumUpdates || NumInserts || NumDeletes) {  
            SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)10, 0);  
            BindOffset = 0;  
         }  
         break;  
   }  
   // }  
  
   // Close the cursor.  
   SQLFreeStmt(hstmt, SQL_CLOSE);  
}  
Mer information om Se
Binda en buffert till en kolumn i en resultatuppsättning SQLBindCol-funktion
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
Positionering av markören, uppdatering av data i raduppsättningen, eller uppdatering eller borttagning av data i raduppsättningen SQLSetPos-funktionen
Ange ett instruktionsattribut SQLSetStmtAttr-funktion