Funkce SQLBulkOperations

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ů:

  1. Spustí dotaz, který vrátí výslednou sadu.

  2. Nastaví atribut SQL_ATTR_ROW_ARRAY_SIZE příkazu na počet řádků, které chce vložit.

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

  4. Volá SQLBulkOperations(StatementHandle, SQL_ADD) pro provedení vložení.

  5. 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í:

  1. Nastaví atribut SQL_ATTR_USE_BOOKMARKS příkazu na SQL_UB_VARIABLE.

  2. Spustí dotaz, který vrátí výslednou sadu.

  3. Nastaví atribut SQL_ATTR_ROW_ARRAY_SIZE příkazu na počet řádků, které chce aktualizovat.

  4. 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).

  5. Kopíruje záložky řádků, které chce aktualizovat, do pole vázaného na sloupec 0.

  6. 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.

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

  8. 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.

  9. 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í:

  1. Nastaví atribut SQL_ATTR_USE_BOOKMARKS příkazu na SQL_UB_VARIABLE.

  2. Spustí dotaz, který vrátí výslednou sadu.

  3. Nastaví atribut SQL_ATTR_ROW_ARRAY_SIZE příkazu na počet řádků, které chce načítat.

  4. 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).

  5. 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.

  6. Volá SQLBulkOperations(StatementHandle, SQL_FETCH_BY_BOOKMARK).

  7. 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í:

  1. Nastaví atribut SQL_ATTR_USE_BOOKMARKS příkazu na SQL_UB_VARIABLE.

  2. Spustí dotaz, který vrátí výslednou sadu.

  3. Nastaví atribut SQL_ATTR_ROW_ARRAY_SIZE příkazu na počet řádků, které chce smazat.

  4. Volá SQLBindCol pro přiřazení sloupce 0 (sloupce záložek).

  5. 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.

  6. Volá SQLBulkOperations(StatementHandle, SQL_DELETE_BY_BOOKMARK).

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

  1. 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.

  2. 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.)

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

  4. 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.

  5. 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);  
}  
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