<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工具的源代碼,學習高技術含量的內容。

      在前面的章節介紹數據查詢時,也是一條條的從結果集中返回數據,大數據量查詢仍然是個瓶頸,好在OCI也提供了批量數據查詢返回結果的處理方法。數組查詢就是為解決這個問題誕生的,它允許一次OCIStmtFetch()操作,返回多行數據。數組查詢的步驟跟單條查詢時區別不大,只是在定義輸出時,輸出變量是數組地址,同樣在OCIDefineByPos()函數后面,要調用OCIDefineArryOfStruct()函數,用于指定數組每個元素跳過的字節數。先看一下原型和參數。

      sword OCIDefineArrayOfStruct ( OCIDefine *defnp,
          OCIError *errhp,
          ub4          pvskip,
          ub4          indskip,
          ub4          rlskip,
          ub4          rcskip );

      跟上一節中OCIBindArrayOfStruct()函數差不多,只是第一個參數變成了定義句柄。

      defnp是一個輸入/輸出參數,定義句柄,OCIDefineByPos()函數隱式分配返回的句柄。

      errhp是一個輸入/輸出參數,錯誤句柄,用于返回錯誤碼和錯誤信息文本。

      pvskip是一個輸入參數,輸出數組中前一個元素與后一個元素需要跳過的字節數。

      indskip是一個輸入參數,指示變量數組要跳過的字節數。

      rlskip是一個輸入參數,返回數據的實際長度數組要跳過的字節數。

      rcskip是一個輸入參數,字段級返回碼數組要跳過的字節數。

      還是以test_tab表為例,從表中查詢數據,使用數組返回查詢結果。與數組插入邏輯差不多,想必你也能很快寫出代碼,但是這里有個問題,插入數據時,我們確切知道插入的條數,可是查詢數據時我們卻不知道返回的條數,當數據條數不夠填滿數組時,我們怎么處理呢?要想辦法知道每次Fetch之后,帶回了多少條數據,還好OCI提供了一種方法。函數OCIAttrGet()函數能夠返回很多句柄的屬性,這里我們就要用到這個函數。先看一下它的原型和參數。

      sword OCIAttrGet ( const void *trgthndlp,
          ub4          trghndltyp,
          void         *attributep,
          ub4          *sizep,
          ub4          attrtype,
          OCIError  *errhp );

      trgthndlp是一個輸入參數,指向一個需要獲取屬性的句柄。

      trghndltyp是一個輸入參數,指定句柄的類型,我們這里用到的是OCI語句句柄OCI_HTYPE_STMT。

      attributep是一個輸出參數,返回屬性值。

      sizep是一個輸出參數,返回屬性值的大小。

      attrtype是一個輸入參數,指定屬性的類型,我們這里用到OCI_ATTR_ROWS_FETCHED

      errhp是一個輸入/輸出參數,錯誤句柄,用于返回錯誤碼和錯誤信息文本。

      獲取每次從結果集中得到的數據實際條數的用法如下。

      ub4    rows;

      ub4    asz = sizeof(ub4);

      OCIAttrGet((const void *)stmtp, (ub4)OCI_HTYPE_STMT,
              (void *)&rows, (ub4 *)&asz, (ub4)OCI_ATTR_ROWS_FETCHED, errhp);

      OCIStmtFetch()函數之后調用上面的函數,rows中就是這次從結果集中返回的數據條數。

      我們還是看一個完整的例子,從test_tab中查詢所有數據,注意看程序是怎樣查詢完畢結束循環的,與單條查詢還是有區別的。

       

      OCIEnv       *envhp = NULL;
      OCIError     *errhp = NULL;
      OCIServer    *svrhp = NULL;
      OCISession   *usrhp = NULL;
      OCISvcCtx    *svchp = NULL;
      OCIStmt      *smthp = NULL;
      
      /* 數組查詢數據 */
      int query_array(void){
          Int         i;
          Sword       rc;
          Int         slen;
          ub4         rrows;
          ub4         asz;
          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        id_str[64];
          char        name[10][32];
          char        addr[10][256];
          OCIDefine   *defp;
          char        sqltxt[1024];
      
          /* 分配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);
          }
      
          /* 生成查詢語句文本 */
          strcpy(sqltxt, "SELECT ID, NAME, ADDR FROM test_tab");
          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,
              OCIDefineByPos((OCIStmt *)smthp,
                  (OCIDefine **)&defp,
                  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)OCI_DEFAULT)   /* mode */
              ) < 0)
              return (-1);
      
          if (check_oci_error(errhp,
              OCIDefineArrayOfStruct(defp, errhp, 4, 2, 2, 2)) < 0)
              return (-1);
      
          /* 定義第二個字段NAME的輸出變量 */
          if (check_oci_error(errhp,
              OCIDefineByPos((OCIStmt *)smthp,
                  (OCIDefine **)&defp,
                  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)OCI_DEFAULT)   /* mode */
              ) < 0)
              return (-1);
      
          if (check_oci_error(errhp,
              OCIDefineArrayOfStruct(defp, errhp, 32, 2, 2, 2)) < 0)
              return (-1);
      
          /*定義第三個字段ADDR的輸出變量 */
          if (check_oci_error(errhp,
              OCIDefineByPos((OCIStmt *)smthp,
                  (OCIDefine **)&defp,
                  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)OCI_DEFAULT)   /* mode */
              ) < 0)
              return (-1);
      
          if (check_oci_error(errhp,
              OCIDefineArrayOfStruct(defp, errhp, 256, 2, 2, 2)) < 0)
              return (-1);
      
          /* 執行OCI語句,注意在查詢語句執行時,iters要設置為0 */
          if (check_oci_error(errhp,
              OCIStmtExecute(svchp,
                  smthp,              /* stmthp */
                  errhp,              /* errhp */
                  0,                  /* iters */
                  0,                  /* rowoff */
                  NULL,               /* snap_in */
                  NULL,               /* snap_out */
                  OCI_DEFAULT)        /* mode */
              ) < 0)
              return (-1);
      
          while (1) {
              /* 注意這里nrows要設置為10,是數組元素的最大個數 */
              if ((rc = check_oci_error(errhp,
                  OCIStmtFetch(smthp, errhp, 10,
                      OCI_FETCH_NEXT, OCI_DEFAULT))) < 0)
                  return (-1);
      
              if (check_oci_error(errhp,
                  OCIAttrGet((const void *)smthp, (ub4)OCI_HTYPE_STMT,
                      (void *)&rrows, (ub4 *)&asz, (ub4)OCI_ATTR_ROWS_FETCHED, errhp)
                  ) < 0)
                  return (-1);
      
              for (i=0; i<rrows; i++) {
                  if (ind_id[i] == -1)
                      sprintf(id_str, "NULL");
                  else
                      sprintf(id_str, "%d", id[i]);
      
                  if (ind_name[i] == -1)
                      sprintf(name[i], "NULL");
                  if (ind_addr[i] == -1)
                      sprintf(addr[i], "NULL");
      
                  fprintf(stdout, "ID=%s, NAME=%s, ADDR=%s\n", id_str, name[i], addr[i]);
              }
      
              /* 結果集中沒有數據了,退出循環,一定要處理完前面的數據再判斷 */
              if (rc == OCI_NO_DATA)
                  break;
          }
      
          return (0);
      }

       

      posted @ 2025-08-14 17:40  湯姆花花  閱讀(13)  評論(0)    收藏  舉報
      主站蜘蛛池模板: аⅴ天堂国产最新版在线中文| 中文字幕日韩有码国产| 综合久久av一区二区三区| 欧美黑人添添高潮a片www| 国产成人亚洲一区二区三区 | 国产一区精品综亚洲av| 精品国产高清中文字幕| 国产成人午夜在线视频极速观看| 中文字幕V亚洲日本在线电影| 国产视频一区二区三区四区视频| 日本欧美一区二区免费视频| 免费人妻av无码专区| 日韩 欧美 亚洲 一区二区| 免费无码又爽又刺激网站直播| 日韩av无码中文无码电影| 国产一区二区三区免费观看| 伊人精品成人久久综合| 免费看的日韩精品黄色片| 亚洲一区二区三区啪啪| 久久久久久综合网天天| 亚洲国产良家在线观看| 国产在线欧美日韩精品一区| 亚洲精品天堂一区二区| 午夜福利理论片高清在线| 国产精品电影久久久久电影网| 成人免费ā片在线观看| 免费无码午夜理论电影| 国产系列高清精品第一页| 精品久久久久久国产| 中文字幕日韩精品有码| 欧美性色黄大片| 亚洲高清激情一区二区三区| 日韩精品国产二区三区| 亚洲色大成网站WWW永久麻豆| 99久久国产精品无码| 大香网伊人久久综合网2020| 国产九九视频一区二区三区| 日本不卡片一区二区三区| 亚洲人成网站18禁止| 国产免费无遮挡吃奶视频| 亚洲精品中文字幕在线观|