<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      OCI編程高級(jí)篇(十七) 直接路徑裝載總結(jié)

      訪問www.tomcoding.com網(wǎng)站,學(xué)習(xí)Oracle內(nèi)部數(shù)據(jù)結(jié)構(gòu),詳細(xì)文檔說明,下載Oracle的exp/imp,DUL,logminer,ASM工具的源代碼,學(xué)習(xí)高技術(shù)含量的內(nèi)容。

      直接路徑裝載的過程其實(shí)跟普通插入沒有太大的區(qū)別,只是設(shè)置更復(fù)雜,步驟覺得雜亂,其實(shí)理解了它的原理,就能自然知道需要哪些步驟。我們先看看插入數(shù)據(jù)有哪些問題。

      1. 要插入數(shù)據(jù)的表名稱是什么?表屬于哪個(gè)schema

      2. 要插入的表有哪些字段啊?字段名稱是什么?數(shù)據(jù)類型是什么?最大長(zhǎng)度是多少?

      3. 程序中的數(shù)據(jù)怎樣和字段關(guān)聯(lián)起來啊?

      4. 怎樣把程序數(shù)據(jù)轉(zhuǎn)換成數(shù)據(jù)庫的數(shù)據(jù)?

      5. 怎樣把數(shù)據(jù)庫數(shù)據(jù)存儲(chǔ)起來啊?

      有了這些問題,我們看看直接路徑裝載是怎樣解決這些問題的。

      首先要分配一個(gè)句柄來存儲(chǔ)表的信息,這個(gè)句柄叫做直接路徑上下文dpctx,分配句柄后要設(shè)置它的屬性,其中有表的schema信息,表的名稱信息,表的字段個(gè)數(shù)。然后從dpctx中得到字段列表描述符,針對(duì)每個(gè)字段設(shè)置字段名稱,數(shù)據(jù)類型,數(shù)據(jù)最大長(zhǎng)度這些屬性。接著要分配一個(gè)句柄來存放表的字段信息,這個(gè)句柄叫直接路徑字段數(shù)組dpca,這個(gè)句柄就能把程序中的數(shù)據(jù)和裝載的字段關(guān)聯(lián)起來,使用OCIDirPathColArrayEntrySet()函數(shù)設(shè)置每行每個(gè)字段的數(shù)據(jù)。最后分配一個(gè)代表數(shù)據(jù)庫數(shù)據(jù)的句柄,這個(gè)句柄叫做直接路徑流dpstr,這個(gè)句柄代表數(shù)據(jù)庫服務(wù)器端的數(shù)據(jù)。dpca代表OCI程序客戶端的數(shù)據(jù),通過OCIDirPathColArrayToStream()函數(shù)就能把客戶端的數(shù)據(jù)轉(zhuǎn)換成服務(wù)器端的數(shù)據(jù)格式,通過OCIDirPathLoadStream()函數(shù)就能指示服務(wù)器端的數(shù)據(jù)存儲(chǔ)到表的塊中。最后通過OCIDirPathFinish()函數(shù)提交裝載的數(shù)據(jù),相當(dāng)于一般插入后的commit操作。

      下面我們把前幾節(jié)中的代碼片段組合成一個(gè)完整的例子,看看直接路徑裝載的完整過程。還是以表test_tab為例,表的屬主用戶(schema)是scott,字段是IDNAMEADDR三個(gè),裝載4次數(shù)據(jù),每次100行,看看循環(huán)設(shè)置數(shù)據(jù)入口和重置狀態(tài)都在哪些位置來操作。

       

      OCIEnv       *envhp = NULL;
      OCIError     *errhp = NULL;
      OCIServer    *svrhp = NULL;
      OCISession   *usrhp = NULL;
      OCISvcCtx    *svchp = NULL;
      struct dp_columns { ub4 dtyp; /* 字段類型 */ ub4 clen; /* 字段最大長(zhǎng)度 */ char name[32]; /* 字段名稱 */ }; int dp_load(void){ int i, r; sword rc, status; ub4 buf_sz; ub4 ncol; ub4 rowcnt; ub4 rowoff; ub4 cvtcnt; OCIDirPathCtx *dpctx; OCIDirPathColArray *dpca; OCIDirPathStream *dpstr; OCIParam *colLst = NULL; OCIParam *colDsc = NULL; struct dp_columms col[3]; ub4 id[100]; char name[100][32]; char addr[100][32]; /* 分配直接路徑上下文句柄,父句柄是envhp */ rc = OCIHandleAlloc((void *)envhp, (void **)&dpctx, OCI_HTYPE_DIRPATH_CTX, 0, (void **)NULL); if (rc != OCI_SUCCESS) { fprintf(stderr, "Allocate direct path context error !\n"); return (-1); } /* 設(shè)置表的schema,在上下文句柄中設(shè)置 */ if (check_oci_error(errhp, OCIAttrSet((void *)dpctx, (ub4)OCI_HTYPE_DIRPATH_CTX, (void *)"scott", strlen("scott"), (ub4)OCI_ATTR_SCHEMA_NAME, errhp) ) < 0) return (-1); /* 設(shè)置表名稱,在上下文句柄中設(shè)置 */ if (check_oci_error(errhp, OCIAttrSet((void *)dpctx, (ub4)OCI_HTYPE_DIRPATH_CTX, (void *)"test_tab", strlen("test_tab"), (ub4)OCI_ATTR_NAME, errhp) ) < 0) return (-1); /* 設(shè)置轉(zhuǎn)換緩沖區(qū)的大小為2M,緩沖區(qū)大小要與字段數(shù)組相適應(yīng), * 太小的話一次轉(zhuǎn)換緩沖區(qū)不夠,會(huì)返回OCI_CONTINUE,需要再次轉(zhuǎn)換 */ buf_sz = 2 * 1024 * 1024; if (check_oci_error(errhp, OCIAttrSet((void *)dpctx, (ub4)OCI_HTYPE_DIRPATH_CTX, (void *)&buf_sz, 0, (ub4)OCI_ATTR_BUF_SIZE, errhp) ) < 0) return (-1); /* 設(shè)置表的字段個(gè)數(shù) */ ncol = 3; if (check_oci_error(errhp, OCIAttrSet((void *)dpctx, (ub4)OCI_HTYPE_DIRPATH_CTX, (void *)&ncol, 0, (ub4)OCI_ATTR_NUM_COLS, errhp) ) < 0) return (-1); /* 獲取字段列表描述符,設(shè)置字段信息 */ if (check_oci_error(errhp, OCIAttrGet((void *)dpctx, (ub4)OCI_HTYPE_DIRPATH_CTX, (void *)&colLst, (ub4)0, (ub4)OCI_ATTR_LIST_COLUMNS, errhp) ) < 0) return (-1); /* 為了方便設(shè)置,我們定義一個(gè)結(jié)構(gòu)存儲(chǔ)字段信息 */ col[0].dtyp = SQLT_INT; col[0].clen = 8; strcpy(col[0].name, "ID"); col[1].dtyp = SQLT_CHR; col[1].clen = 30; strcpy(col[1].name, "NAME"); col[2].dtyp = SQLT_CHR; col[2].clen = 200; strcpy(col[2].name, "ADDR"); for (i=0; i<ncol; i++) { /* 獲取字段描述符,這個(gè)描述符是隱式獲得,需要釋放,否則會(huì)造成內(nèi)存泄露 * 這里字段的位置從1開始編號(hào) */ if (check_oci_error(errhp, OCIParamGet((const void *)colLst, (ub4)OCI_DTYPE_PARAM, errhp, (void **)&colDsc, (ub4)(i+1)) ) < 0) return (-1); /* 設(shè)置字段的屬性,字段名稱 */ if (check_oci_error(errhp, OCIAttrSet((void *)colDsc, (ub4)OCI_DTYPE_PARAM, (void *)col[i].name, (ub4)strlen(col[i].name), (ub4)OCI_ATTR_NAME, errhp) ) < 0) return (-1); /* 設(shè)置字段數(shù)據(jù)類型 */ if (check_oci_error(errhp, OCIAttrSet((void *)colDsc, (ub4)OCI_DTYPE_PARAM, (void *)&col[i].dtyp, (ub4)0, (ub4)OCI_ATTR_DATA_TYPE, errhp) ) < 0) return (-1); /* 設(shè)置字段的數(shù)據(jù)最大長(zhǎng)度 */ if (check_oci_error(errhp, OCIAttrSet((void *)colDsc, (ub4)OCI_DTYPE_PARAM, (void *)&col[i].clen, (ub4)0, (ub4)OCI_ATTR_DATA_SIZE, errhp) ) < 0) return (-1); } /* 釋放掉字段描述符 */ OCIDescriptorFree((void *)colDsc, (ub4)OCI_DTYPE_PARAM); /* 設(shè)置完所有字段后,要把字段列表的描述符也釋放掉 */ OCIDescriptorFree((void *)colLst, (ub4)OCI_DTYPE_PARAM); /* 設(shè)置完屬性后,準(zhǔn)備直接路徑裝載 */ if (check_oci_error(errhp, OCIDirPathPrepare(dpctx, svchp, errhp)) < 0) return (-1);? /* 分配直接路徑字段數(shù)組句柄,父句柄是dpctx */ rc = OCIHandleAlloc((void *)dpctx, (void **)&dpca, OCI_HTYPE_DIRPATH_COLUMN_ARRAY, 0, (void **)NULL); if (rc != OCI_SUCCESS) { fprintf(stderr, "Allocate direct path column array handle error !\n"); return (-1); } /* 分配直接路徑流句柄,父句柄是dpctx */ rc = OCIHandleAlloc((void *)dpctx, (void **)&dpstr, OCI_HTYPE_DIRPATH_STREAM, 0, (void **)NULL); if (rc != OCI_SUCCESS) { fprintf(stderr, "Allocate direct path stream handle error !\n"); return (-1); } /* 循環(huán)4次,每次裝載100行數(shù)據(jù) */ for (r=0; r<4; r++) { /* 這里生成100行數(shù)據(jù),在真實(shí)的環(huán)境中數(shù)據(jù)可能來自文件或其他數(shù)據(jù)源 * 為了演示方便,直接把name和addr設(shè)置成了相同的數(shù)據(jù) */ for (i=0; i<100; i++) { id = i + 100; /* id從100開始計(jì)數(shù) */ strcpy(name[i], "AAAAAAAAAA"); strcpy(addr[i], "BBBBBBBBBBBBBBBB"); } /* 循環(huán)設(shè)置每一行每一列的數(shù)據(jù)入口 */ for (i=0; i<100; i++) { /* 設(shè)置第一列ID的數(shù)據(jù)入口,列索引是從0開始的 */ if (check_oci_error(errhp, OCIDirPathColArrayEntrySet(dpca, errhp, (ub4)i, (ub2)0, (ub1*)&id[i], 4, OCI_DIRPATH_COL_COMPLETE) ) < 0) return (-1); /* 設(shè)置第二列NAME的數(shù)據(jù)入口,列索引是1 */ if (check_oci_error(errhp, OCIDirPathColArrayEntrySet(dpca, errhp, (ub4)i, (ub2)1, (ub1 *)name[i], (ub4)strlen(name[i]), OCI_DIRPATH_COL_COMPLETE) ) < 0) return (-1); /* 設(shè)置第三列ADDR的數(shù)據(jù)入口,列索引是2 */ if (check_oci_error(errhp, OCIDirPathColArrayEntrySet(dpca, errhp, (ub4)i, (ub2)2, (ub1 *)addr[i], (ub4)strlen(addr[i]), OCI_DIRPATH_COL_COMPLETE) ) < 0) return (-1); } /* 重置直接路徑字段數(shù)組的狀態(tài) */ if (check_oci_error(errhp, OCIDirPathColArrayReset(dpca, errhp)) < 0) return (-1); /* 重置直接路徑流的狀態(tài) */ if (check_oci_error(errhp, OCIDirPathStreamReset(dpstr, errhp)) < 0) return (-1); /* 轉(zhuǎn)換字段數(shù)組到流數(shù)據(jù),然后裝載流數(shù)據(jù),一共轉(zhuǎn)換100行數(shù)據(jù),從第0行開始 */ rowcnt = 100; rowoff = 0; while (1) { status = OCIDirPathColArrayToStream(dpca, dpctx, dpstr, errhp, (ub4)rowcnt, (ub4)rowoff); if (status == OCI_CONTINUE) { /* 轉(zhuǎn)換緩沖區(qū)過小,數(shù)據(jù)沒有轉(zhuǎn)換完,得到已經(jīng)轉(zhuǎn)換的行數(shù) */ if (check_oci_error(errhp, OCIAttrGet((const void *)dpca, OCI_HTYPE_DIRPATH_COLUMN_ARRAY, (void *)(&cvtcnt), (ub4 *)0, OCI_ATTR_ROW_COUNT, errhp) ) < 0) return (-1); rowcnt -= cvtcnt; rowoff += cvtcnt; } else { if (check_oci_error(errhp, status) < 0) return (-1); } /* 裝載數(shù)據(jù) */ if (check_oci_error(errhp, OCIDirPathLoadStream(dpctx, dpstr, errhp)) < 0) return (-1); /* 如果前面的轉(zhuǎn)換全部完成,現(xiàn)在裝載也成功了,說明這100條數(shù)據(jù)裝載完成 * 退出while()循環(huán) */ if (status == OCI_SUCCESS) break; /* 程序到這里,說明還有未轉(zhuǎn)換完的數(shù)據(jù),重置直接路徑流的狀態(tài),進(jìn)行下一次轉(zhuǎn)換, * 下次轉(zhuǎn)換從新的rowoff位置開始,轉(zhuǎn)換條數(shù)為新的rowcnt條 */ if (check_oci_error(errhp, OCIDirPathStreamReset(dpstr, errhp)) < 0) return (-1); } /* while()循環(huán)的結(jié)束邊界 */ /* 裝載完了100條數(shù)據(jù),進(jìn)入下一循環(huán),裝載另外的100條數(shù)據(jù),或者全部裝載完退出循環(huán) */ } /* for()循環(huán)的結(jié)束邊界 */ /* 數(shù)據(jù)全部裝載完,提交裝載的數(shù)據(jù) */ if (check_oci_error(errhp, OCIDirPathFinish(dpctx, errhp)) < 0) return (-1); /* 釋放前面分配的句柄 */ OCIHandleFree((void *)dpca, OCI_HTYPE_DIRPATH_COLUMN_ARRAY); OCIHandleFree((void *)dpstr, OCI_HTYPE_DIRPATH_STREAM); OCIHandleFree((void *)dpctx, OCI_HTYPE_DIRPATH_CTX); return (0); }

       

      到這里OCI的直接路徑裝載就介紹完了,上面的例子演示了一個(gè)完整的過程,包括數(shù)據(jù)轉(zhuǎn)換中遇到的一些問題的解決方法,多看幾遍就能對(duì)直接路徑裝載的流程全面掌握。

       

      posted @ 2025-08-14 21:54  湯姆花花  閱讀(6)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产99视频精品免费专区| 国产99在线 | 亚洲| 97人人模人人爽人人少妇| 国产午夜视频在线观看| 熟女人妻精品一区二区视频| 老王亚洲AV综合在线观看| 中文区中文字幕免费看| 久久精品青青大伊人av| 成人午夜福利一区二区四区| 少妇高潮喷水惨叫久久久久电影| 亚洲偷自拍国综合| 元码人妻精品一区二区三区9| 国产999久久高清免费观看| 天堂中文在线资源| 免费av深夜在线观看| 国产国产午夜福利视频| 久久久av男人的天堂| 天天躁日日躁狠狠躁中文字幕| 亚洲成av人在线播放无码| 妖精视频yjsp毛片永久| 四虎在线成人免费观看| 搡老熟女老女人一区二区 | 东莞市| 久久97超碰色中文字幕| 日韩乱码人妻无码中文字幕视频| 小婕子伦流澡到高潮h| 国产精品成人网址在线观看| 国产午夜福利小视频在线| 免费看婬乱a欧美大片| 国产精品国产高清国产av| 日韩一区二区三区在线视频| 熟妇无码熟妇毛片| 日韩成人无码影院| 亚洲综合不卡一区二区三区| 午夜AAAAA级岛国福利在线 | 精品无码一区二区三区在线| 国语对白刺激在线视频国产网红| 激情综合色综合啪啪开心| 成熟丰满熟妇av无码区| 亚洲中文字幕在线二页| 苍井空毛片精品久久久|