Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Soulad
Představená verze: ODBC 3.0 Shoda standardů: ODBC
Summary
SQLBulkOperations provádí hromadné vkládání a hromadné operace záložek, včetně aktualizace, mazání a načítání podle záložek.
Syntax
SQLRETURN SQLBulkOperations(
SQLHSTMT StatementHandle,
SQLUSMALLINT Operation);
Arguments
StatementHandle
[Vstup] Popisovač příkazu
Operation
[Vstup] Operace, kterou je třeba provést:
SQL_ADD SQL_UPDATE_BY_BOOKMARK SQL_DELETE_BY_BOOKMARK SQL_FETCH_BY_BOOKMARK
Pro více informací viz "Komentáře."
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR nebo SQL_INVALID_HANDLE.
Diagnostika
Když SQLBulkOperations vrátí SQL_ERROR nebo SQL_SUCCESS_WITH_INFO, lze získat přidruženou hodnotu SQLSTATE voláním SQLGetDiagRec pomocí HandleType SQL_HANDLE_STMT a HandleCommandHandle. Následující tabulka uvádí hodnoty SQLSTATE, které SQLBulkOperations obvykle vrací, a vysvětluje každou z nich v kontextu této funkce; notace "(DM)" předchází popisům SQLstavů vráceným Správcem ovladačů. Návratový kód přidružený ke každé hodnotě SQLSTATE je SQL_ERROR, pokud není uvedeno jinak.
Pro všechny ty SQLSTATE, které mohou vrátit SQL_SUCCESS_WITH_INFO nebo SQL_ERROR (kromě 01xxx SQLSTATE), SQL_SUCCESS_WITH_INFO se vrací, pokud se chyba objeví na jednom nebo více, ale ne na všech, řádcích víceřádkové operace, a SQL_ERROR se vrací, pokud chyba nastane při jednořádkové operaci.
| SQLSTATE | Error | Description |
|---|---|---|
| 01000 | Obecné upozornění | Informační zpráva specifická pro řidiče (Funkce vrátí SQL_SUCCESS_WITH_INFO.) |
| 01004 | Pravé ořezávání datových řetězců | Argument Operation byl SQL_FETCH_BY_BOOKMARK a řetězcová nebo binární data vrácená pro sloupec nebo sloupce s datovým typem SQL_C_CHAR nebo SQL_C_BINARY vedly k okrácení neblankových znaků nebo ne-NULL binárních dat. |
| 01S01 | Chyba v řádku | Argument operace byl SQL_ADD a při provádění operace došlo k chybě v jednom nebo více řádcích, ale alespoň jeden řádek byl úspěšně přidán. (Funkce vrátí SQL_SUCCESS_WITH_INFO.) (Tato chyba se objeví pouze tehdy, když aplikace pracuje s ODBC 2. x driver.) |
| 01S07 | Zlomkové zkrácení | Argument Operation byl SQL_FETCH_BY_BOOKMARK, datový typ aplikačního bufferu nebyl SQL_C_CHAR ani SQL_C_BINARY a data vrácená do aplikačních bufferů pro jeden nebo více sloupců byla zkrácena. (U číselných C datových typů byla zlomková část čísla zkrácena. U časových, časových a intervalových C datových typů, které obsahují časovou složku, byla zlomková část času zkrácena.) (Funkce vrátí SQL_SUCCESS_WITH_INFO.) |
| 07006 | Porušení atributu omezeného datového typu | Argument Operation byl SQL_FETCH_BY_BOOKMARK a datová hodnota sloupce ve výsledné sadě nemohla být převedena na datový typ specifikovaný argumentem TargetType ve volání SQLBindCol. Argument Operation byl SQL_UPDATE_BY_BOOKMARK nebo SQL_ADD a datová hodnota v aplikačních bufferech nemohla být převedena na datový typ sloupce ve výsledné sadě. |
| 07009 | Index neplatných deskriptorů | Argument Operation byl SQL_ADD a sloupec byl vázán číslem sloupce větším než počet sloupců ve výsledné množině. |
| 21S02 | Stupeň odvozené tabulky neodpovídá seznamu sloupců | Argumentem byla operace SQL_UPDATE_BY_BOOKMARK; a žádné sloupce nebyly aktualizovatelné, protože všechny sloupce byly buď nevázané, nebo pouze pro čtení, nebo hodnota v bufferu pro délku/indikátor byla SQL_COLUMN_IGNORE. |
| 22001 | Pravé ořezávání datových řetězců | Přiřazení znaku nebo binární hodnoty ke sloupci ve výsledné sadě vedlo k okrácení neprázdných (pro znaky) nebo nenulových (pro binárních) znaků či bajtů. |
| 22003 | Číselná hodnota mimo rozsah | Argument Operation byl SQL_ADD nebo SQL_UPDATE_BY_BOOKMARK a přiřazení číselné hodnoty sloupci ve výsledné množině způsobilo zkrácení celé (na rozdíl od zlomkové) části čísla. Argument Operation byl SQL_FETCH_BY_BOOKMARK a vrácení číselné hodnoty pro jeden nebo více vázaných sloupců by způsobilo ztrátu významných číslic. |
| 22007 | Neplatný formát data a času | Argument Operace byl SQL_ADD nebo SQL_UPDATE_BY_BOOKMARK a přiřazení hodnoty data nebo časového razítka ke sloupci ve výsledné sadě způsobilo, že pole rok, měsíc nebo den bylo mimo rozsah. Argument Operace byl SQL_FETCH_BY_BOOKMARK a vrácení hodnoty data nebo časového razítka pro jeden nebo více vázaných sloupců by způsobilo, že pole rok, měsíc nebo den bylo mimo rozsah. |
| 22008 | Přetečení dat/čas pole | Argument Operation byl SQL_ADD nebo SQL_UPDATE_BY_BOOKMARK a provedení aritmetiky datového času na datech odeslaných do sloupce ve výsledné sadě vedlo k tomu, že pole datového času (rok, měsíc, den, hodina, minuta nebo druhé pole) výsledku bylo mimo povolený rozsah hodnot pro dané pole nebo bylo neplatné podle přirozených pravidel gregoriánského kalendáře pro datové časy. Argument Operace byl SQL_FETCH_BY_BOOKMARK a provedení aritmetiky datového času na datech získaných z výsledné sady vedlo k tomu, že pole datového času (rok, měsíc, den, hodina, minuta nebo druhé pole) výsledku bylo mimo povolený rozsah hodnot pro dané pole nebo bylo neplatné podle přirozených pravidel gregoriánského kalendáře pro daty. |
| 22015 | Přetečení pole intervalu | Argument Operation byl SQL_ADD nebo SQL_UPDATE_BY_BOOKMARK a přiřazení přesného numerického nebo intervalového typu C k intervalovému SQL datovému typu způsobilo ztrátu významných číslic. Argument Operace byl SQL_ADD nebo SQL_UPDATE_BY_BOOKMARK; při přiřazení SQL typu interval nebyla v intervalovém SQL typu reprezentována hodnota typu C. Argument Operation byl SQL_FETCH_BY_BOOKMARK a přiřazení z přesného numerického nebo intervalového SQL typu k intervalovému typu C způsobilo ztrátu významných číslic v vedoucím poli. Argument Operace byl SQL_FETCH_BY_BOOKMARK; při přiřazení typu C intervalu nebyla v intervalu C uvedena hodnota SQL typu. |
| 22018 | Neplatná hodnota znaku pro specifikaci přetypování | Argument Operace byl SQL_FETCH_BY_BOOKMARK; typ C byl přesný nebo přibližný číselný typ, datový čas nebo intervalový datový typ; SQL typ sloupce byl datový typ znaku; a hodnota ve sloupci nebyla platným literálem vázaného typu C. Argument Operace byl SQL_ADD nebo SQL_UPDATE_BY_BOOKMARK; SQL typ byl přesná nebo přibližná číselná číslo, datový čas nebo intervalový datový typ; typ C byl SQL_C_CHAR; a hodnota ve sloupci nebyla platným literálem vázaného SQL typu. |
| 23000 | Porušení omezení integrity | Argument Operace byl SQL_ADD, SQL_DELETE_BY_BOOKMARK nebo SQL_UPDATE_BY_BOOKMARK a bylo porušeno omezení integrity. Argument Operation byl SQL_ADD a sloupec, který nebyl vázaný, je definován jako NOT NULL a nemá výchozí nastavení. Argument Operation byl SQL_ADD, délka uvedená v bufferu StrLen_or_IndPtr byla SQL_COLUMN_IGNORE a sloupec neměl výchozí hodnotu. |
| 24000 | Neplatný stav kurzoru | CommandHandle byl ve stavu vykonání, ale žádná výsledná sada nebyla spojena s StatementHandle. |
| 40001 | Selhání serializace | Transakce byla vrácena zpět kvůli vzájemnému zablokování prostředku s jinou transakcí. |
| 40003 | Neznámé dokončování příkazů | Přidružené připojení se nezdařilo během provádění této funkce a stav transakce nelze určit. |
| 42000 | Chyba syntaxe nebo porušení přístupu | Řidič nebyl schopen uzamknout řádek, jak bylo nutné pro provedení operace požadované v argumentu Operace . |
| 44000 | PORUŠENÍ FUNKCE CHECK OPTION | Argument Operace byl SQL_ADD nebo SQL_UPDATE_BY_BOOKMARK a vložení nebo aktualizace byla provedena na zobrazené tabulce (nebo tabulce odvozené z této tabulky), která byla vytvořena zadáním S MOŽNOSTÍ ZAŠKRTNOUT, tak, že jeden nebo více řádků ovlivněných vložením nebo aktualizací již nebude v zobrazené tabulce přítomno. |
| HY000 | Obecná chyba | Došlo k chybě, pro kterou nebyla definována žádná specifická funkce SQLSTATE a pro kterou nebyla definována žádná implementace sqlSTATE. Chybová zpráva vrácená nástrojem SQLGetDiagRec v vyrovnávací paměti *MessageText popisuje chybu a její příčinu. |
| HY001 | Chyba přidělení paměti | Ovladač nemohl přidělit paměť potřebnou k podpoře provádění nebo dokončení funkce. |
| HY008 | Operace byla zrušena. | Asynchronní zpracování bylo povoleno pro StatementHandle. Funkce byla volána a před dokončením provádění byla volána funkce SQLCancel nebo SQLCancelHandle pro PříkazHandle. Pak byla funkce znovu volána v StatementHandle. Funkce byla volána a před dokončením provádění byla volána funkce SQLCancel neboSQLCancelHandlez jiného vlákna v aplikaci s více vlákny. |
| HY010 | Chyba posloupnosti funkcí | (DM) Byla volána asynchronně spuštěná funkce pro popisovač připojení, který je přidružen k StatementHandle. Tato asynchronní funkce se stále vykonávala, když byla volána funkce SQLBulkOperations . (DM) SQLExecute, SQLExecDirect nebo SQLMoreResults byl volána pro StatementHandle a vrácena SQL_PARAM_DATA_AVAILABLE. Tato funkce byla volána před načtením dat pro všechny streamované parametry. (DM) Specifikovaný StatementHandle nebyl ve stavu vykonání. Funkce byla volána bez předchozího volání SQLExecDirect, SQLExecute nebo katalogové funkce. (DM) Pro PříkazHandle byla volána asynchronně spuštěná funkce (ne tato) a při zavolání této funkce se stále spouštěla. (DM) SQLExecute, SQLExecDirect nebo SQLSetPos byl vyvolán pro StatementHandle a vrátil SQL_NEED_DATA. Tato funkce byla volána před odesláním dat pro všechny parametry provádění dat nebo sloupce. (DM) Řidič byl ODBC 2. x driver, a SQLBulkOperations byl volán pro CommandHandle dříve, než byl volán SQLFetchScroll nebo SQLFetch . (DM) SQLBulkOperations byl vyvolán poté, co byl SQLExtendedFetch vyvolán na CommandHandle. |
| HY011 | Atribut nelze nyní nastavit | (DM) Řidič byl ODBC 2. x ovladač a atribut SQL_ATTR_ROW_STATUS_PTR příkazu byl nastaven mezi voláními SQLFetch nebo SQLFetchScroll a SQLBulkOperations. |
| HY013 | Chyba správy paměti | Volání funkce nelze zpracovat, protože základní objekty paměti nelze získat přístup, pravděpodobně kvůli nedostatku paměti. |
| HY090 | Neplatná délka řetězce nebo vyrovnávací paměti | Argument Operace byl SQL_ADD nebo SQL_UPDATE_BY_BOOKMARK; Hodnota dat nebyla nulovým ukazatelem; datový typ C byl SQL_C_BINARY nebo SQL_C_CHAR; a délka sloupce byla menší než 0, ale nebyla rovna SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NTS nebo SQL_NULL_DATA, ani menší či rovna SQL_LEN_DATA_AT_EXEC_OFFSET. Hodnota v bufferu délky/indikátoru byla SQL_DATA_AT_EXEC; SQL typ byl buď SQL_LONGVARCHAR, SQL_LONGVARBINARY, nebo dlouhý datový typ specifický pro datový zdroj; a SQL_NEED_LONG_DATA_LEN informační typ v SQLGetInfo byl "Y". Argument Operation byl SQL_ADD, atribut SQL_ATTR_USE_BOOKMARK byl nastaven na SQL_UB_VARIABLE a sloupec 0 byl vázán na buffer, jehož délka nebyla rovna maximální délce záložky pro tuto sadu výsledků. (Tato délka je dostupná v SQL_DESC_OCTET_LENGTH poli IRD a lze ji získat voláním SQLDescribeCol, SQLColAttribute nebo SQLGetDescField.) |
| HY092 | Neplatný identifikátor atributu | (DM) Hodnota uvedená pro argument Operace byla neplatná. Argument Operation byl SQL_ADD, SQL_UPDATE_BY_BOOKMARK nebo SQL_DELETE_BY_BOOKMARK a atribut SQL_ATTR_CONCURRENCY příkazu byl nastaven na SQL_CONCUR_READ_ONLY. Argument Operace byl SQL_DELETE_BY_BOOKMARK, SQL_FETCH_BY_BOOKMARK nebo SQL_UPDATE_BY_BOOKMARK a sloupec záložek nebyl vázaný ani atribut SQL_ATTR_USE_BOOKMARKS příkazu nebyl nastaven na SQL_UB_OFF. |
| HY117 | Připojení je pozastaveno kvůli neznámému stavu transakce. Jsou povoleny pouze funkce pro odpojení a jen pro čtení. | (DM) Další informace o pozastaveném stavu naleznete v tématu FUNKCE SQLEndTran. |
| HYC00 | Nepovinná funkce není implementována. | Ovladač nebo zdroj dat nepodporuje operaci požadovanou v argumentu Operation . |
| HYT00 | Vypršel časový limit. | Platnost časového limitu dotazu vypršela, než zdroj dat vrátil sadu výsledků. Časová doba je nastavena pomocí SQLSetStmtAttr s argumentem atributu SQL_ATTR_QUERY_TIMEOUT. |
| HYT01 | Vypršel časový limit připojení | Platnost časového limitu připojení vypršela, než zdroj dat odpověděl na žádost. Časový limit připojení je nastavený prostřednictvím sqlSetConnectAttr SQL_ATTR_CONNECTION_TIMEOUT. |
| IM001 | Ovladač tuto funkci nepodporuje. | (DM) Ovladač přidružený k StatementHandle nepodporuje funkci. |
| IM017 | Dotazování je zakázané v asynchronním režimu oznámení. | Při každém použití modelu oznámení je dotazování zakázané. |
| IM018 | K dokončení předchozí asynchronní operace na tomto popisovači nebyla volána funkce SQLCompleteAsync. | Pokud předchozí volání funkce na popisovači vrátí SQL_STILL_EXECUTING a pokud je povolen režim oznámení, musí být sqlCompleteAsync volán na popisovači, aby bylo možné provést následné zpracování a dokončit operaci. |
Comments
Caution
Pro informace o tom, jaký příkaz uvádí, že lze volat SQLBulkOperations a co musí udělat pro kompatibilitu s ODBC 2. x aplikace, viz sekce Blokové kurzory, Posuvné kurzory a zpětná kompatibilita v Příloze G: Pokyny pro zpětnou kompatibilitu ovladačů.
Aplikace používá SQLBulkOperations k provedení následujících operací na základní tabulce nebo pohledu, který odpovídá aktuálnímu dotazu:
Přidejte nové řádky.
Aktualizujte sadu řádků, kde je každý řádek označen záložkou.
Smažte sadu řádků, kde je každý řádek označen záložkou.
Načítejte sadu řádků, kde je každý řádek označen záložkou.
Po volání do SQLBulkOperations není pozice kurzoru bloku definována. Aplikace musí zavolat SQLFetchScroll pro nastavení pozice kurzoru. Aplikace by měla volat SQLFetchScroll pouze s argumentem FetchOrientation SQL_FETCH_FIRST, SQL_FETCH_LAST, SQL_FETCH_ABSOLUTE nebo SQL_FETCH_BOOKMARK. Pozice kurzoru není definována, pokud aplikace volá SQLFetch nebo SQLFetchScroll s argumentem FetchOrientation SQL_FETCH_PRIOR, SQL_FETCH_NEXT nebo SQL_FETCH_RELATIVE.
Sloupec lze ignorovat v hromadných operacích prováděných voláním SQLBulkOperations nastavením délky sloupce/indikátorové buffer specifikované ve volání SQLBindCol na SQL_COLUMN_IGNORE.
Aplikace nemusí při volání SQLBulkOperations nastavovat atribut SQL_ATTR_ROW_OPERATION_PTR příkazu, protože řádky nelze ignorovat při hromadných operacích s touto funkcí.
Buffer, na který odkazuje atribut SQL_ATTR_ROWS_FETCHED_PTR příkazu, obsahuje počet řádků ovlivněných voláním SQLBulkOperations.
Když je argument Operace SQL_ADD nebo SQL_UPDATE_BY_BOOKMARK a seznam dotazů přiřazených kurzoru obsahuje více než jednu referenci na stejný sloupec, je ovladačem definováno, zda je chyba generována, nebo ovladač ignoruje duplicitní odkazy a vykoná požadované operace.
Pro více informací o používání SQLBulkOperations viz Aktualizace dat pomocí SQLBulkOperations.
Provádění hromadných insertů
Pro vložení dat pomocí SQLBulkOperations aplikace provede následující sekvenci kroků:
Spustí dotaz, který vrátí výslednou sadu.
Nastaví atribut SQL_ATTR_ROW_ARRAY_SIZE příkazu na počet řádků, které chce vložit.
Volá SQLBindCol , aby navázal data, která chce vložit. Data jsou vázána na pole o velikosti rovné hodnotě SQL_ATTR_ROW_ARRAY_SIZE.
Note
Velikost pole na kterou ukazuje atribut SQL_ATTR_ROW_STATUS_PTR příkazu by měla být buď rovna SQL_ATTR_ROW_ARRAY_SIZE, nebo SQL_ATTR_ROW_STATUS_PTR by měla být nulový ukazatel.
Volá SQLBulkOperations(StatementHandle, SQL_ADD) pro provedení vložení.
Pokud aplikace nastavila atribut SQL_ATTR_ROW_STATUS_PTR příkazu, může toto pole prohlédnout a vidět výsledek operace.
Pokud aplikace připojí sloupec 0 před zavoláním SQLBulkOperations argumentem Operation o hodnotě SQL_ADD, ovladač aktualizuje buffery ve svázaném sloupci 0 hodnotami záložek pro nově vložený řádek. Aby k tomu došlo, musí aplikace nastavit atribut SQL_ATTR_USE_BOOKMARKS příkazu na SQL_UB_VARIABLE před vykonáním příkazu. (To nefunguje s ODBC 2. x driver.)
Dlouhá data lze přidávat po částech pomocí SQLBulkOperations, pomocí volání SQLParamData a SQLPutData. Pro více informací viz "Poskytování dlouhých dat pro hromadné vložení a aktualizace" později v této referenční sekci.
Není nutné, aby aplikace volala SQLFetch nebo SQLFetchScroll před zavoláním SQLBulkOperations (kromě případů, kdy jde proti ODBC 2.x driver; viz Zpětná kompatibilita a dodržování standardů).
Chování je definováno ovladačem, pokud je SQLBulkOperations s argumentem Operation SQL_ADD vyvolán na kurzoru obsahujícím duplicitní sloupce. Ovladač může vrátit SQLSTATE definovaný ovladačem, přidat data do prvního sloupce, který se objeví ve výsledné sadě, nebo provést jiné chování definované ovladačem.
Provádění hromadných aktualizací pomocí záložek
Pro provádění hromadných aktualizací pomocí záložek se SQLBulkOperations aplikace provádí následující kroky v pořadí:
Nastaví atribut SQL_ATTR_USE_BOOKMARKS příkazu na SQL_UB_VARIABLE.
Spustí dotaz, který vrátí výslednou sadu.
Nastaví atribut SQL_ATTR_ROW_ARRAY_SIZE příkazu na počet řádků, které chce aktualizovat.
Volá SQLBindCol , aby svázal data, která chce aktualizovat. Data jsou vázána na pole o velikosti rovné hodnotě SQL_ATTR_ROW_ARRAY_SIZE. Také volá SQLBindCol pro přiřazení sloupce 0 (sloupce záložek).
Kopíruje záložky řádků, které chce aktualizovat, do pole vázaného na sloupec 0.
Aktualizuje data ve vázaných bufferech.
Note
Velikost pole na kterou ukazuje atribut SQL_ATTR_ROW_STATUS_PTR příkazu by měla být roven SQL_ATTR_ROW_ARRAY_SIZE nebo SQL_ATTR_ROW_STATUS_PTR by měl být nulový ukazatel.
Volá SQLBulkOperations(StatementHandle, SQL_UPDATE_BY_BOOKMARK).
Note
Pokud aplikace nastavila atribut SQL_ATTR_ROW_STATUS_PTR příkazu, může toto pole prohlédnout a vidět výsledek operace.
Volitelně volá SQLBulkOperations(StatementHandle, SQL_FETCH_BY_BOOKMARK), aby načetl data do vázaných aplikačních bufferů a ověřil, že aktualizace proběhla.
Pokud byla data aktualizována, ovladač změní hodnotu v řádkovém stavovém poli pro příslušné řádky na SQL_ROW_UPDATED.
Hromadné aktualizace prováděné SQLBulkOperations mohou zahrnovat dlouhá data pomocí volání SQLParamData a SQLPutData. Pro více informací viz "Poskytování dlouhých dat pro hromadné vložení a aktualizace" později v této referenční sekci.
Pokud záložky přetrvávají přes kurzory, aplikace nemusí volat SQLFetch nebo SQLFetchScroll před aktualizací záložek. Může používat záložky, které má uložené z předchozího kurzoru. Pokud záložky nepřetrvávají přes kurzory, aplikace musí zavolat SQLFetch nebo SQLFetchScroll , aby záložky získala.
Chování je definováno ovladačem, pokud je SQLBulkOperations s argumentem Operation SQL_UPDATE_BY_BOOKMARK vyvolán na kurzoru obsahujícím duplicitní sloupce. Ovladač může vrátit SQLSTATE definovaný ovladačem, aktualizovat první sloupec, který se objeví ve výsledné sadě, nebo provádět jiné chování definované ovladačem.
Provádění hromadného načítání pomocí záložek
Pro hromadné načítání pomocí záložek se SQLBulkOperations aplikace provádí následující kroky v pořadí:
Nastaví atribut SQL_ATTR_USE_BOOKMARKS příkazu na SQL_UB_VARIABLE.
Spustí dotaz, který vrátí výslednou sadu.
Nastaví atribut SQL_ATTR_ROW_ARRAY_SIZE příkazu na počet řádků, které chce načítat.
Volá SQLBindCol , aby navázal data, která chce načítat. Data jsou vázána na pole o velikosti rovné hodnotě SQL_ATTR_ROW_ARRAY_SIZE. Také volá SQLBindCol pro přiřazení sloupce 0 (sloupce záložek).
Zkopíruje záložky řádků, které chce načítat, do pole vázaného na sloupec 0. (To předpokládá, že aplikace již záložky získala samostatně.)
Note
Velikost pole na kterou ukazuje atribut SQL_ATTR_ROW_STATUS_PTR příkazu by měla být roven SQL_ATTR_ROW_ARRAY_SIZE nebo SQL_ATTR_ROW_STATUS_PTR by měl být nulový ukazatel.
Volá SQLBulkOperations(StatementHandle, SQL_FETCH_BY_BOOKMARK).
Pokud aplikace nastavila atribut SQL_ATTR_ROW_STATUS_PTR příkazu, může toto pole prohlédnout a vidět výsledek operace.
Pokud záložky přetrvávají přes kurzory, aplikace nemusí volat SQLFetch nebo SQLFetchScroll před načítáním záložek. Může používat záložky, které má uložené z předchozího kurzoru. Pokud záložky nepřetrvávají přes kurzory, aplikace musí jednou zavolat SQLFetch nebo SQLFetchScroll , aby záložky získala.
Provádění hromadných mazání pomocí záložek
Pro hromadné mazání pomocí záložek v SQLBulkOperations aplikace provádí následující kroky v pořadí:
Nastaví atribut SQL_ATTR_USE_BOOKMARKS příkazu na SQL_UB_VARIABLE.
Spustí dotaz, který vrátí výslednou sadu.
Nastaví atribut SQL_ATTR_ROW_ARRAY_SIZE příkazu na počet řádků, které chce smazat.
Volá SQLBindCol pro přiřazení sloupce 0 (sloupce záložek).
Kopíruje záložky řádků, které chce smazat, do pole vázaného na sloupec 0.
Note
Velikost pole na kterou ukazuje atribut SQL_ATTR_ROW_STATUS_PTR příkazu by měla být roven SQL_ATTR_ROW_ARRAY_SIZE nebo SQL_ATTR_ROW_STATUS_PTR by měl být nulový ukazatel.
Volá SQLBulkOperations(StatementHandle, SQL_DELETE_BY_BOOKMARK).
Pokud aplikace nastavila atribut SQL_ATTR_ROW_STATUS_PTR příkazu, může toto pole prohlédnout a vidět výsledek operace.
Pokud záložky přetrvávají přes kurzory, aplikace nemusí před smazáním záložek volat SQLFetch nebo SQLFetchScroll . Může používat záložky, které má uložené z předchozího kurzoru. Pokud záložky nepřetrvávají přes kurzory, aplikace musí jednou zavolat SQLFetch nebo SQLFetchScroll , aby záložky získala.
Poskytování dlouhých dat pro hromadné vložení a aktualizace
Dlouhá data lze poskytnout pro hromadné vklady a aktualizace prováděné voláním SQLBulkOperations. Pro vložení nebo aktualizaci dlouhých dat aplikace provádí následující kroky kromě kroků popsaných v sekcích "Provádění hromadných vkladů" a "Provádění hromadných aktualizací pomocí záložek" dříve v tomto tématu.
Když aplikace sváže data pomocí SQLBindCol, umístí aplikací definovanou hodnotu, například číslo sloupce, do bufferu *TargetValuePtr pro sloupce dat při vykonání. Hodnota může být později použita k identifikaci sloupce.
Aplikace umístí výsledek makra SQL_LEN_DATA_AT_EXEC(délka) do bufferu *StrLen_or_IndPtr . Pokud je SQL datový typ sloupce SQL_LONGVARBINARY, SQL_LONGVARCHAR nebo dlouhý datový typ specifický pro zdroj dat a ovladač vrací "Y" pro SQL_NEED_LONG_DATA_LEN informační typ v SQLGetInfo, délka je počet bajtů dat, která mají být odeslána pro parametr; jinak musí být nezáporná hodnota a je ignorována.
Když je volán SQLBulkOperations , pokud jsou zde sloupce dat při vykonání, funkce vrátí SQL_NEED_DATA a pokračuje do kroku 3, který následuje. (Pokud nejsou žádné sloupce dat při vykonání, proces je dokončen.)
Aplikace volá SQLParamData k získání adresy bufferu *TargetValuePtr pro první kolonu dat-at-exekuci, která má být zpracována. SQLParamData vrací SQL_NEED_DATA. Aplikace získává hodnotu definovanou aplikací z bufferu *TargetValuePtr .
Note
Ačkoliv parametry dat při vykonání připomínají sloupce dat při vykonání, hodnota vrácená SQLParamData je pro každý z nich jiná.
Sloupce Data-at-execution jsou sloupce v sadě řádků, pro které budou data odeslána spolu se SQLPutData při aktualizaci nebo vložení řádku pomocí SQLBulkOperations. Jsou vázáni na SQLBindCol. Hodnota vrácená SQLParamData je adresa řádku v bufferu *TargetValuePtr , který je zpracováván.
Aplikace volá SQLPutData jednou nebo vícekrát, aby odesla data do sloupce. Pokud nelze všechny datové hodnoty vrátit do bufferu *TargetValuePtr specifikovaného v SQLPutData, je potřeba více než jedno volání; více volání SQLPutData pro stejný sloupec je povoleno pouze při odesílání dat znaku C do sloupce s typem znaku, binárního souboru nebo datového zdroje specifického, nebo při odesílání binárních dat C do sloupce se znakem, binárním nebo datovým typem specifickým pro zdroj dat.
Aplikace znovu volá SQLParamData , aby signalizovala, že všechna data pro sloupec byla odeslána.
Pokud je více sloupců dat-at-exekuci, SQLParamData vrátí SQL_NEED_DATA a adresu bufferu TargetValuePtr pro další sloupec dat-at-exekuce, který má být zpracován. Aplikace opakuje kroky 4 a 5.
Pokud již nejsou žádné sloupce dat při vykonání, proces je dokončen. Pokud byl příkaz úspěšně vykonán, SQLParamData vrací SQL_SUCCESS nebo SQL_SUCCESS_WITH_INFO; pokud provedení selže, vrátí SQL_ERROR. V tomto bodě může SQLParamData vrátit jakýkoli SQLSTATE, který SQLBulkOperations dokáže vrátit.
Pokud je operace zrušena nebo dojde k chybě v SQLParamData nebo SQLPutData poté, co SQLBulkOperations vrátí SQL_NEED_DATA a před odesláním dat pro všechny sloupce při vykonání dat, může aplikace volat pouze SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions, SQLParamData nebo SQLPutData pro příkaz nebo spojení spojené s tímto příkazem. Pokud zavolá jinou funkci pro příkaz nebo spojení spojené s tímto příkazem, funkce vrátí SQL_ERROR a SQLSTATE HY010 (chyba sekvence funkce).
Pokud aplikace volá SQLCancel, zatímco ovladač stále potřebuje data pro sloupce dat-at-exekuce, ovladač operaci zruší. Aplikace pak může znovu volat SQLBulkOperations ; Zrušení neovlivňuje stav kurzoru ani aktuální pozici kurzoru.
Pole stavu řádku
Pole stavů řádku obsahuje stavové hodnoty pro každý řádek dat v sadě řádků po volání do SQLBulkOperations. Ovladač nastavuje stavové hodnoty v tomto poli po volání do SQLFetch, SQLFetchScroll, SQLSetPos nebo SQLBulkOperations. Toto pole je zpočátku vyplněno voláním SQLBulkOperations , pokud SQLFetch nebo SQLFetchScroll nebyly před SQLBulkOperations vyvolány. Toto pole je označeno atributem SQL_ATTR_ROW_STATUS_PTR statement. Počet prvků v stavových poli řádků musí být roven počtu řádků v sadě řádků (jak je definováno atributem SQL_ATTR_ROW_ARRAY_SIZE příkazu). Pro informace o tomto stavovém poli řádků viz SQLFetch.
Příklad kódu
Následující příklad načítá najednou 10 řádků dat z tabulky Zákazníci. Poté uživatele vyzve k akci, kterou má provést. Pro snížení síťového provozu se příkladová vyrovnávací paměť aktualizuje, maže a vkládá lokálně do vázaných polí, ale s posuny za daty řádků. Když uživatel zvolí posílání aktualizací, mazání a vkladání do datového zdroje, kód správně nastaví offset vázaní a zavolá SQLBulkOperations. Pro jednoduchost uživatel nemůže uložit více než 10 aktualizací, smazání nebo vložení.
// 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);
}
Související funkce
| Informace o | Podívejte se |
|---|---|
| Vytvoření vazby vyrovnávací paměti ke sloupci v sadě výsledků | SQLBindCol – funkce |
| Zrušení zpracování příkazů | SQLCancel – funkce |
| Načtení bloku dat nebo procházení sady výsledků | SQLFetchScroll – funkce |
| Získání jednoho pole deskriptoru | SQLGetDescField Function |
| Získání více polí deskriptoru | SQLGetDescRec Function |
| Nastavení jednoho pole deskriptoru | SQLSetDescField Function |
| Nastavení více polí deskriptoru | SQLSetDescRec Function |
| Umístění kurzoru, obnovení dat v sadě řádků nebo aktualizace či smazání dat v sadě řádků | Funkce SQLSetPos |
| Nastavení atributu příkazu | FUNKCE SQLSetStmtAttr |