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

      連接到數據庫的過程中要分配好幾個句柄,我們先看看連接到數據庫需要哪幾步。首先需要有一個連接數據庫的對象,接著這個對象要與數據庫服務器建立關系,然后需要創建一個會話,會話需要用戶名和密碼來認證,接下來要啟動會話,這樣就建立了一個用戶會話到數據庫的連接。到這里還沒完,還要創建一個服務上下文,把服務器對象和會話都放到上下文中,這樣在后面用戶修改數據時,才能提交事務,提交事務的函數要用到服務上下文。

      分配服務器句柄

      使用前面介紹的分配句柄的函數OCIHandleAlloc()分配一個服務器句柄,句柄類型為OCI_HTYPE_SERVER,父句柄還是OCI的環境句柄envhp

      sword               rc;

      OCIEnv            *envhp;

      OCIServer       *svrhp

      rc = OCIHandleAlloc(
              (const void *)envhp,
              (void **)&svrhp,
              OCI_HTYPE_SERVER,
              0,
              (void **)NULL
      );  
      if (rc != OCI_SUCCESS) {
              fprintf(stderr, "OCIHandleAlloc() - allocate server handle error !\n");
              return (-1);
      }

      建立到服務器的連接

      分配完服務器句柄,就要用它連接到服務器,這一步用到的函數叫做OCIServerAttach(),建立一條與Oracle服務器的通信路徑。看一下函數原型和參數。

      sword OCIServerAttach ( OCIServer *srvhp,
          OCIError         *errhp,
          const OraText *dblink,
          sb4                  dblink_len,
          ub4                  mode );

      srvhp是一個輸入/輸出參數,輸入的是前面分配的句柄,指向一片未初始化的內存,函數調用后,這片內存就被初始化了。不能傳入一個已經建立連接的句柄,否則會報錯。

      errhp是一個輸入/輸出參數,輸入的是前面分配的出錯句柄,調用函數出錯后,輸出的句柄包含錯誤信息。

      dblink是一個輸入參數,這是一個字符串,用于指示連接數據庫的信息。如果使用TNS連接數據庫,那么這兒就是TNS名稱。如果使用連接字符串,有兩種格式,一種是//ip:port/service_name,另一種就是類似TNS配置中的格式(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=ip)(PORT=port))(CONNECT_DATA=(SERVICE_NAME=service_name)))。舉例,如果Oracle服務器ip地址為192.168.10.110,端口port1521,服務名service_nameorcl,那么第一種連接格式為//192.168.10.110:1521/orcl,第二種連接格式為(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.10.110)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)))。如果dblink賦值為NULL的話,會連接本機的Oracle服務器。

      dblink_len是一個輸入參數,表示上面連接字符串的長度,如果dblinkNULL,在這里賦值為0

      mode是一個輸入參數,指定連接的模式,有兩個值,一個是OCI_DEFAULT,缺省模式,另一個是OCI_CPOOL,連接池模式。一般用缺省模式就可以了。

      函數調用成功后,Oracle數據庫的后臺就會啟動一個進程,與這個連接關聯起來。看一個例子,連接到本地數據庫。

      sword               rc;

      OCIError          *errhp;

      OCIServer       *svrhp;

      rc = OCIServerAttach(
              svrhp,
              errhp,
              (const OraText *)NULL,
              0,
              OCI_DEFAULT
      );

      if (rc != OCI_SUCCESS) {
              fprintf(stderr, "OCIServerAttach() - attach server error !\n");
              return (-1);            
      }

      開始一個會話

      連接到數據庫以后,下一步就是啟動一個用戶到數據庫的會話過程,用到的函數叫做OCISessionBegin()。不過在開始會話前要先分配一個會話句柄,類型為OCI_HTYPE_SESSION,然后還要給句柄設置用戶名和密碼的屬性,這樣才能開始一個用戶會話。下面是分配會話句柄的例子。

      OCIEnv             *envhp;

      OCISession      *usrhp;

      rc = OCIHandleAlloc(
              (void *)envhp,
              (void **)&usrhp,
              OCI_HTYPE_SESSION,
              0,
              (void **)NULL
      );

      if (rc != OCI_SUCCESS) {
              fprintf(stderr, "OCIHandleAlloc() - allocate session handle error !\n");
              return (-1);
      }

      為會話句柄設置屬性,要用到一個函數叫做 OCIAttrSet(),先看一下函數原型和參數。

      sword OCIAttrSet ( void *trgthndlp,
          ub4          trghndltyp,
          void         *attributep,
          ub4          size,
          ub4          attrtype,
          OCIError *errhp );

      trgthndlp是一個輸入/輸出參數,是要設置屬性的句柄。這里就是會話句柄。

      trghndltyp是一個輸入/輸出參數,是要設置屬性的句柄類型。這里是OCI_HTYPE_SESSION

      attributep是一個輸入參數,是要設置的屬性值,如果文本屬性,就指向一個字符串,如果是整數屬性,就指向一個整數的地址。

      size是一個輸入參數,是要設置的屬性值的大小,大多數時候設置為0,函數可以根據屬性類型知道屬性值的大小,如果屬性是文本,那么必須輸入文本的長度。

      attrtype是一個輸入參數,是要設置屬性的類型。我們要設置用戶屬性,這里的類型為OCI_ATTR_USERNAME

      errhp是一個輸入/輸出參數,是函數調用出錯后返回錯誤信息用的。

      如果用戶名為hr,密碼為passwd,那么設置會話屬性的示例如下。

      /* 設置用戶屬性 */
      rc = OCIAttrSet(
              (void *)usrhp,
              OCI_HTYPE_SESSION,
              (void *)"hr",
              strlen("hr"),
              OCI_ATTR_USERNAME,
              errhp
      );

      if (rc != OCI_SUCCESS) {
              fprintf(stderr, "Set user attribute error !\n");
              return (-1);
      }

      /* 設置密碼屬性 */
      rc = OCIAttrSet(
              (void *)usrhp,
              OCI_HTYPE_SESSION,
              (void *)"passwd",
              strlen("passwd"),
              OCI_ATTR_PASSWORD,
              errhp
      );

      if (rc != OCI_SUCCESS) {
              fprintf(stderr, "Set password attribute error !\n");
              return (-1);
      }

      下面就是開啟一個會話,先看一下OCISessionBegin()函數的原型和參數。

      sword OCISessionBegin ( OCISvcCtx *svchp,
          OCIError      *errhp,
          OCISession *usrhp,
          ub4               credt,
          ub4               mode );

      svchp是一個輸入參數,是服務的上下文句柄,前面說過,服務器句柄svrhp與數據庫建立連接之后,要放到上下文中,這個參數就是要輸入上下文句柄。

      errhp是一個輸入參數,用于返回出錯信息。

      usrhp是一個輸入/輸出參數,就是前面創建的會話句柄。

      credt是一個輸入參數,指定建立會話的認證類型。如果需要數據庫的用戶和密碼認證,取值為OCI_CRED_RDBMS,如果使用外部認證,取值為OCI_CRED_EXT

      mode是一個輸入參數,指定不同的操作模式,一般取值為OCI_DEFAULT就可以。

      從上面看到,在調用OCISessionBegin()函數之前,需要先分配一個服務上下文句柄,并且把建立的數據庫連接服務句柄方進去,下面我們就完成這步操作。

      OCISvcCtx       *svchp;

      OCIServer        *svrhp;

      sword                rc;

      /* 分配服務上下文句柄 */
      rc = OCIHandleAlloc(
              (void *)envhp,
              (void **)&svchp,
              OCI_HTYPE_SVCCTX,
              0,
              (void **)NULL
      );

      if (rc != OCI_SUCCESS) {
              fprintf(stderr, "OCIHandleAlloc() - allocate server context error !\n");
              return (-1);
      }

      /* 把服務器句柄放入服務上下文句柄中 */
      rc = OCIAttrSet(
              (void *)svchp,
              OCI_HTYPE_SVCCTX,
              (void *)svrhp,
              0,
              OCI_ATTR_SERVER,
              errhp
      );

      if (rc != OCI_SUCCESS) {
              fprintf(stderr, "Set server attribute error !\n");
              return (-1);
      }

      現在終于可以開始會話了,然后把會話句柄加入到服務上下文句柄中。

      rc = OCISessionBegin(
              svchp,
              errhp,
              usrhp,
              OCI_CRED_RDBMS,
              OCI_DEFAULT
      );

      if (rc != OCI_SUCCESS) {
              fprintf(stderr, "OCISessionBegin() - establish user session error !\n");
              return (-1);
      }

      rc = OCIAttrSet(
              (void *)svchp,
              OCI_HTYPE_SVCCTX,
              (void *)usrhp,
              0,
              OCI_ATTR_SESSION,
              errhp
      );

      if (rc != OCI_SUCCESS) {
              fprintf(stderr, "Set user session attribute error !\n");
              return (-1);
      }

      到現在為止,我們已經連接到了Oracle數據庫上,后面就可以進行對數據庫的訪問了。

      是不是看完上面的內容,還是不知道怎樣建立一個數據庫連接?下一節我們看一個完整的程序,里面有詳細的步驟和函數調用的先后順序,看完就會完全明白的。

      posted @ 2025-08-13 20:54  湯姆花花  閱讀(16)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 极品少妇无套内射视频| 中文午夜乱理片无码| 四虎永久免费高清视频| 精品亚洲国产成人| 亚洲国产成人久久精品app| 亚洲一区在线成人av| 成人精品久久一区二区三区| 亚洲区欧美区综合区自拍区| 精品国产一区二区三区久| 国产精品无码久久久久AV| 久久国产免费观看精品3| 成人午夜视频一区二区无码| 亚在线观看免费视频入口| 亚洲大尺度一区二区三区| 东京热tokyo综合久久精品| 亚洲高清日韩专区精品| 99热这里只有精品免费播放| 99久久久国产精品免费无卡顿 | 久久国产精品波多野结衣| 人妻丝袜AV中文系列先锋影音| 国产精品毛片在线完整版| 午夜DY888国产精品影院| 天堂√最新版中文在线地址| 亚洲成人动漫在线| 无码专区视频精品老司机| 尹人香蕉久久99天天拍| 成人精品日韩专区在线观看 | 综合色一色综合久久网| 怡红院一区二区三区在线| 国产精品一区二区三区四区| 内射干少妇亚洲69xxx| 2022最新国产在线不卡a| 人妻系列无码专区久久五月天| 色欲久久人妻内射| 欧美色欧美亚洲高清在线观看| 欧美性猛交xxxx黑人| 99麻豆久久精品一区二区| 少妇xxxxx性开放| 4hu44四虎www在线影院麻豆 | 亚洲av色香蕉一二三区| 国产国拍亚洲精品永久软件|