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

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

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

      OCI編程高級篇(三) 批量執行

      訪問www.tomcoding.com網站,學習Oracle內部數據結構,詳細文檔說明,下載Oracle的exp/imp,DUL,logminer,ASM工具的源代碼,學習高技術含量的內容。

      前面我們討論了數組插入數據的過程,實際上Oracle還是一條條的執行數組中的元素,只不過是一次性的提供了多條數據而已。當數據單條執行時,如果出現了錯誤,我們確切的知道是那一條出了錯,修改數據后再執行就可以了。但是數組插入讓我們遇到了問題,數組中的數據只要有一條出現了錯誤,整個數組插入操作就會報錯,并且錯誤行后面的數據不會再執行,這時只能先回滾掉所有的操作,然后找出錯誤數據行,修正后,再重新執行數組操作。如果數組中有多條錯誤,那會嚴重影響效率,并且程序員處理這些錯誤也會非常頭痛。

      那么有沒有什么好的方法來避免上面的麻煩呢?答案是肯定的,OCI提供了一種機制,叫做執行的批量錯誤模式,在這一模式下,OCI會執行數組中的每一條數據,然后收集錯誤行的信息,OCI程序可以返回每個錯誤行的出錯信息,然后修正數據,只需要重新執行錯誤行數據就可以了。

      批量錯誤模式的處理步驟如下。

      1. 分配OCI語句。

      2. 準備SQL語句文本。

      3. 綁定數組數據。

      4. 執行語句,使用OCI_BATCH_ERRORS模式。

      5. 獲取出錯行的數量,使用OCI_ATTR_NUM_DML_ERRORS調用OCIAttrGet()函數。

      6. 獲取每個錯誤的錯誤碼和錯誤信息文本

      7. 處理錯誤。

      在第六步中用到了一個函數OCIParamGet()用于取得每個錯誤的錯誤句柄。

      sword OCIParamGet ( const void *hndlp,
          ub4          htype,
          OCIError *errhp,
          void         **parmdpp,
          ub4          pos );

      hndlp是一個輸入參數,是要獲取參數的句柄,我們在這里使用錯誤句柄。

      htype是一個輸入參數,是句柄的類型,這里是OCI_HTYPE_ERROR

      errhp是一個輸入/輸出參數,是一個錯誤句柄,用于OCIErrorGet()取回錯誤信息。

      parmdpp是一個輸出參數,參數值,在這里我們要取回一個錯誤句柄。

      pos是一個輸入參數,這里是錯誤的位置號,從0開始。

      還是用前面數組插入的例子,看看用OCI_BATCH_ERRORS模式怎樣處理錯誤。

       

      OCIEnv       *envhp = NULL;
      OCIError     *errhp = NULL;
      OCIServer    *svrhp = NULL;
      OCISession   *usrhp = NULL;
      OCISvcCtx    *svchp = NULL;
      OCIStmt      *smthp = NULL;
      
      OCIError    *errhp1 = NULL;
      OCIError    *errhp2 = NULL;
      /* 數組插入10條數據 */
      int insert_array_batch(void){
          int        i;
          sword      rc;
          int        slen;
          ub4        num_errs;
          ub4        row_off;
          sb4        ecode;
          sb2        ind_id[10];
          sb2        ind_name[10];
          sb2        ind_addr[10];
          ub2        alen_id[10];
          ub2        alen_name[10];
          ub2        alen_addr[10];
          ub2        rcode_id[10];
          ub2        rcode_name[10];
          ub2        rcode_addr[10];
          int32_t    id[10];
          char       name[10][32];
          char       addr[10][256];
          OCIBind    *bndp;
          char       sqltxt[1024];
          char       errmsg1[16384];
      
          /* 分配OCI語句句柄 */
          rc = OCIHandleAlloc(
              (void *)envhp,
              (void **)&smthp,
              OCI_HTYPE_STMT,
              0,
              (void **)NULL
          );
      
          if (rc != OCI_SUCCESS) {
              fprintf(stderr, "OCIHandleAlloc() - allocate statement handle error !\n");
              return (-1);
          }
      
          /* 生成SQL語句文本 */
          strcpy(sqltxt, "INSERT INTO test_tab (ID, NAME, ADDR) VALUES (:1, :2, :3)");
          slen = strlen(sqltxt);
      
          /* 準備語句 */
          if (check_oci_error(errhp,
              OCIStmtPrepare(smthp, errhp, (const OraText *)sqltxt, slen,
                  OCI_NTV_SYNTAX, OCI_DEFAULT)) < 0)
              return (-1);
      
          /* 綁定第一個占位符ID,綁定數組地址 */
          if (check_oci_error(errhp,
              OCIBindByPos((OCIStmt *)smthp,
                  (OCIBind **)&bndp,
                  errhp,
                  (ub4)1,                /* position */
                  (void *)id,         /* valuep */
                  (sb4)4,             /* value_sz */
                  (ub2)SQLT_INT,      /* dty */
                  (void *)ind_id,     /* indp */
                  (ub2 *)alen_id,     /* alenp */
                  (ub2 *)rcode_id,    /* column return code pointer */
                  (ub4)0,             /* maxarr_len */
                  (ub4 *)NULL,        /* curelep */
                  (ub4)OCI_DEFAULT)   /* mode */
              ) < 0)
              return (-1);
      
          /* 指定綁定參數跳過的字節數 */
          if (check_oci_error(errhp,
              OCIBindArrayOfStruct(bndp,
                  sizeof(int32_t),
                  sizeof(sb2),
                  sizeof(ub2),
                  sizeof(ub2))
              ) < 0)
              return (-1);
      
          /* 綁定第二個占位符NAME */
          if (check_oci_error(errhp,
              OCIBindByPos((OCIStmt *)smthp,
                  (OCIBind **)&bndp,
                  errhp,
                  (ub4)2,             /* position */
                  (void *)name,       /* valuep */
                  (sb4)30,            /* value_sz */
                  (ub2)SQLT_STR,      /* dty */
                  (void *)ind_name,   /* indp */
                  (ub2 *)alen_name,   /* alenp */
                  (ub2 *)rcode_name,  /* column return code pointer */
                  (ub4)0,             /* maxarr_len */
                  (ub4 *)NULL,        /* curelep */
                  (ub4)OCI_DEFAULT)   /* mode */
              ) < 0)
              return (-1);
      
          /* 指定綁定參數跳過的字節數,name定義的長度為32 */
          if (check_oci_error(errhp,
              OCIBindArrayOfStruct(bndp,
                  32,
                  sizeof(sb2),
                  sizeof(ub2),
                  sizeof(ub2))
              ) < 0)
              return (-1);
      
          /* 綁定第三個占位符ADDR */
          if (check_oci_error(errhp,
              OCIBindByPos((OCIStmt *)smthp,
                  (OCIBind **)&bndp,
                  errhp,
                  (ub4)3,             /* position */
                  (void *)addr,       /* valuep */
                  (sb4)200,           /* value_sz */
                  (ub2)SQLT_STR,      /* dty */
                  (void *)ind_addr,   /* indp */
                  (ub2 *)alen_addr,   /* alenp */
                  (ub2 *)rcode_addr,  /* column return code pointer */
                  (ub4)0,             /* maxarr_len */
                  (ub4 *)NULL,        /* curelep */
                  (ub4)OCI_DEFAULT)   /* mode */
              ) < 0)
              return (-1);
      
          /* 指定綁定參數跳過的字節數,addr定義的長度為256 */
          if (check_oci_error(errhp,
              OCIBindArrayOfStruct(bndp,
                  256,
                  sizeof(sb2),
                  sizeof(ub2),
                  sizeof(ub2))
              ) < 0)
              return (-1);
      
          /* 賦值綁定的變量數據 */
          for (i=0; i<10; i++) {
              id[i] = i+10;
              memset(name[i], 'a', 10);
              memset(addr[i], 'b', 20);
      
              name[i][10] = '\0';
              addr[i][20] = '\0';
      
              /* 指示符賦值為0,插入非NULL數據 */
              ind_id[i]    = 0;
              ind_name[i]  = 0;
              ind_addr[i]  = 0;
      
              /* 賦值變量的真實數據長度 */
              alen_id[i]   = sizeof(int32_t);
              alen_name[i] = strlen(name[i]) + 1;
              alen_addr[i] = strlen(addr[i]) + 1;
          }
      
          /* 執行OCI語句,注意這里要用OCI_BATCH_ERRORS模式 */
          if (check_oci_error(errhp,
              OCIStmtExecute(svchp,
                  smthp,              /* stmthp */
                  errhp,              /* errhp */
                  10,                 /* iters */
                  0,                  /* rowoff */
                  NULL,               /* snap_in */
                  NULL,               /* snap_out */
                  OCI_BATCH_ERRORS)   /* mode */
              ) < 0)
              return (-1);
      
          /* 分配錯誤句柄errhp1,用于取回錯誤條數 */
          if (check_oci_error(errhp,
              OCIHandleAlloc((const void *)envhp, (void **)&errhp1,
                  OCI_HTYPE_ERROR, 0, (void **)NULL)) < 0)
              return (-1);
      
          if (check_oci_error(errhp,
              OCIAttrGet (smthp, OCI_HTYPE_STMT, &num_errs, 0,
                  OCI_ATTR_NUM_DML_ERRORS, errhp1)) < 0)
              return (-1);
      
          if (num_errs) {
              /* 分配錯誤句柄errhp2 */
              if (check_oci_error(errhp,
                  OCIHandleAlloc((const void *)envhp, (void **)&errhp2,
                      OCI_HTYPE_ERROR, 0, (void **)NULL)) < 0)
                  return (-1);
      
              for (i=0; i<num_errs; i++) {
                  if (check_oci_error(errhp,
                      OCIParamGet(errhp, OCI_HTYPE_ERROR, errhp1, &errhp2, i)) < 0)
                      return (-1);
      
                  if (check_oci_error(errhp,
                      OCIAttrGet (errhp2, OCI_HTYPE_ERROR, &row_off, 0,
                          OCI_ATTR_DML_ROW_OFFSET, errhp1)) < 0)
                      return (-1);
      
                  OCIErrorGet(errhp2, 1, NULL, &ecode, (OraText *)errmsg1,
                      16383, OCI_HTYPE_ERROR);
      
                  fprintf(stderr, "row[%d] error: %d-%s\n", row_off, ecode, errmsg1);
                  fprintf(stderr, "ID=%d, NAME=%s, ADDR=%s\n",
                      id[row_off], name[row_off], addr[row_off]);
              }
          }
      
          /* 提交改變的數據 */
          if (check_oci_error(errhp,
              OCITransCommit(svchp, errhp, OCI_DEFAULT)) < 0)
              return (-1);
      
          return (0);
      }

       

      posted @ 2025-08-14 17:44  湯姆花花  閱讀(9)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产成人av电影在线观看第一页 | 亚洲人午夜射精精品日韩| 青青青久热国产精品视频| 中文字幕人妻中文AV不卡专区| 精品无码久久久久国产| 亚洲精品一区二区美女| 成人av一区二区亚洲精| 亚洲AV成人片不卡无码| 日韩av第一页在线播放| 中文在线天堂中文在线天堂| 欧美成本人视频免费播放| 亚洲精品岛国片在线观看| 综合图区亚洲另类偷窥| 亚洲国产美国产综合一区| 亚洲真人无码永久在线| 大胸少妇午夜三级| 日本欧美大码a在线观看| 亚洲av永久无码精品漫画| 伊春市| 最新精品露脸国产在线| 日本精品一区二区不卡| 日本亚洲一级中文字幕| 少妇又爽又刺激视频| 亚洲成人av在线系列| 日韩欧国产美一区二区在线| 午夜国产小视频| 鲜城| 日韩不卡在线观看视频不卡| 99精品国产精品一区二区| 蜜臀av一区二区精品字幕| 极品少妇xxxx| 99在线视频免费观看| av色蜜桃一区二区三区| 噜噜综合亚洲av中文无码| 日韩人妻无码精品系列| 加勒比无码人妻东京热| 欧美不卡无线在线一二三区观| 国产精品任我爽爆在线播放6080| 天天狠天天透天天伊人| 成人精品一区二区三区四| 午夜射精日本三级|