Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Ö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 SQLCancelHandle på StatementHandle. Sedan anropades funktionen igen på StatementHandle. Funktionen anropades och innan körningen slutfördes anropades SQLCancel eller SQLCancelHandle på StatementHandle 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:
Exekverar en fråga som returnerar en resultatuppsättning.
Sätter attributet SQL_ATTR_ROW_ARRAY_SIZE statement till antalet rader som den vill infoga.
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.
Anropar SQLBulkOperations(StatementHandle, SQL_ADD) för att utföra insättningen.
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:
Sätter attributet SQL_ATTR_USE_BOOKMARKS statement till SQL_UB_VARIABLE.
Exekverar en fråga som returnerar en resultatuppsättning.
Sätter attributet SQL_ATTR_ROW_ARRAY_SIZE statement till antalet rader som den vill uppdatera.
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).
Kopierar bokmärkena för rader som den är intresserad av att uppdatera till arrayen bunden till kolumn 0.
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.
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.
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.
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:
Sätter attributet SQL_ATTR_USE_BOOKMARKS statement till SQL_UB_VARIABLE.
Exekverar en fråga som returnerar en resultatuppsättning.
Sätter attributet SQL_ATTR_ROW_ARRAY_SIZE till antalet rader som den vill hämta.
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).
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.
anropar SQLBulkOperations(StatementHandle, SQL_FETCH_BY_BOOKMARK).
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:
Sätter attributet SQL_ATTR_USE_BOOKMARKS statement till SQL_UB_VARIABLE.
Exekverar en fråga som returnerar en resultatuppsättning.
Sätter attributet SQL_ATTR_ROW_ARRAY_SIZE till antalet rader som den vill ta bort.
Anropar SQLBindCol för att binda kolumn 0 (bokmärkeskolumnen).
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.
anropar SQLBulkOperations(StatementHandle, SQL_DELETE_BY_BOOKMARK).
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.
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.
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.)
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.
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.
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);
}
Relaterade funktioner
| 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 |