已閱讀5頁,還剩56頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
OCI 學(xué)習(xí)學(xué)習(xí)資料資料 Oracle8 及以后版本的 OCI 1 簡介簡介 Oracle 調(diào)用接口 Oracle Call Interface 是一個(gè)讓我們通過函數(shù)調(diào)用來訪問 Oracle 數(shù)據(jù)庫和 控制 SQL 語句執(zhí)行各個(gè)階段的應(yīng)用程序編程接口 API OCI 支持 C 和 C 的數(shù)據(jù)類型 調(diào)用 慣例 語法和語義 1 1 創(chuàng)建一個(gè)創(chuàng)建一個(gè) OCI 應(yīng)用程序應(yīng)用程序 我們編譯和連接一個(gè) OCI 程序的方法與編譯和連接一個(gè)非數(shù)據(jù)庫應(yīng)用程序的方法相同 不需要獨(dú)立的預(yù)處理或者預(yù)編譯步驟 1 2 OCI 的組成部分的組成部分 OCI 具有如下功能 能夠安全地支持大量用戶的靈活的 多線程 API 集合 為管理數(shù)據(jù)庫訪問 處理 SQL 語句和管理 Oracle 數(shù)據(jù)庫對象的 SQL 訪問函數(shù) 管理 Oracle 類型的數(shù)據(jù)屬性的數(shù)據(jù)類型映射和操作函數(shù) 不經(jīng) SQL 語句直接向數(shù)據(jù)庫加載數(shù)據(jù)的數(shù)據(jù)加載函數(shù) 1 3 封裝的接口封裝的接口 所有的 OCI 函數(shù)使用的數(shù)據(jù)結(jié)構(gòu)都以被稱為句柄的不透明的接口之形式封裝 句柄是指 向 OCI 庫分配的保存著上下文信息 連接信息 錯(cuò)誤信息或者關(guān)于 SQL 及 PL SQL 的綁定信 息的不透明指針 客戶端分配一定類型的句柄 通過已經(jīng)定義好的接口來填充一個(gè)或者多個(gè) 句柄 并通過這些句柄向服務(wù)器發(fā)送請求 應(yīng)用程序可以通過訪問函數(shù)來訪問句柄中包含的 相關(guān)信息 2 OCI 基本編程基本編程 這部分介紹 OCI 編程中涉及到的基本概念 2 1 OCI 編程概要編程概要 一個(gè) OCI 應(yīng)用程序的基本目標(biāo)就是代表多個(gè)用戶進(jìn)行數(shù)據(jù)庫操作 OCI 使用以下基本編程順序 1 初始化 OCI 編程環(huán)境和線程 2 分配必要的句柄 并且設(shè)置服務(wù)器連接和用戶會(huì)話 3 通過在服務(wù)器上執(zhí)行 SQL 語句來交換數(shù)據(jù) 并且執(zhí)行必要的應(yīng)用程序數(shù)據(jù)處理 4 執(zhí)行準(zhǔn)備好的語句或者準(zhǔn)備即將要執(zhí)行的語句 5 終止用戶會(huì)話并且斷開服務(wù)器連接 6 釋放句柄 圖 2 1 顯示了一個(gè) OCI 應(yīng)用程序的編程步驟 圖 2 1 這幅圖及其所列出的步驟提供了一個(gè) OCI 編程步驟的簡單概括 根據(jù)程序的功能 變 化是完全可能發(fā)生的 包含管理多個(gè)會(huì)話 事務(wù)和使用對象的更復(fù)雜的 OCI 應(yīng)用程序需要 另外的步驟 所有的 OCI 函數(shù)調(diào)用都在一個(gè)環(huán)境中執(zhí)行 在一個(gè) OCI 進(jìn)程中可以有多個(gè)環(huán)境 如果 一個(gè)環(huán)境需要任何進(jìn)程級別的初始化 則其自動(dòng)進(jìn)行 注意 注意 在一個(gè)在一個(gè) OCI 應(yīng)用程序中應(yīng)用程序中可以有多個(gè)活動(dòng)連接和語句 可以有多個(gè)活動(dòng)連接和語句 2 2 OCI 數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu) 句柄 Handles 和描述符 descriptors 是 OCI 應(yīng)用程序中定義的不透明的數(shù)據(jù)結(jié)構(gòu) 它們可 以被直接分配 通過特殊的分配函數(shù)或者可以被 OCI 函數(shù)隱式地分配 7 X 升級注意 升級注意 以前寫過以前寫過 7 XOCI 應(yīng)用程序的應(yīng)用程序的程序員必須程序員必須熟悉熟悉這些被大多數(shù)這些被大多數(shù) OCI 函數(shù)使函數(shù)使 用的數(shù)據(jù)結(jié)構(gòu) 用的數(shù)據(jù)結(jié)構(gòu) 句柄和描述符保存有關(guān)數(shù)據(jù) 連接 或者應(yīng)用程序行為的信息 2 3 句柄句柄 幾乎每一個(gè) OCI 函數(shù)的參數(shù)列表中都包含有一個(gè)或者多個(gè)句柄 一個(gè)句柄是一個(gè)指向一 個(gè) OCI 庫分配的存儲(chǔ)區(qū)域的不透明的指針 我們使用句柄來保存上下文信息或者連接信 息 例如 一個(gè)環(huán)境或者服務(wù)句柄 或者它可以保存關(guān)于 OCI 函數(shù)或者數(shù)據(jù)的信息 例如 一個(gè)錯(cuò)誤句柄或者描述句柄 句柄可以使編程更簡單 因?yàn)?OCI 庫會(huì)維持這些數(shù)據(jù)而不 是應(yīng)用程序 大多數(shù) OCI 應(yīng)用程序需要使用句柄中的信息 獲取屬性值和設(shè)置屬性值的 OCI 函數(shù) OCIAttrGet 和 OCIAttrSet 獲取和設(shè)置這些信息 表 2 1 列出了 OCI 中定義的句柄 并列出了與每一種句柄類型相對應(yīng)的 C 數(shù)據(jù)類型和 OCI 函數(shù)中使用的用來識別 OCI 調(diào)用中的句柄類型的句柄類型常量 表表 2 1 OCI 句柄類型句柄類型 分配和釋放句柄分配和釋放句柄 我們的應(yīng)用程序要為一個(gè)特定的環(huán)境句柄分配所有的句柄 除了綁定句柄 bind handle 定義句柄 define handle 和線程句柄 thread handles 我們把環(huán)境句柄作為一個(gè)參數(shù)傳遞至 句柄分配函數(shù) 然后 被分配的句柄就特定于那個(gè)特定的環(huán)境 綁定句柄和定義句柄是為一個(gè)語句句柄分配的 并且包含了關(guān)于那個(gè)句柄所代表的語句 的信息 注意 注意 綁定句柄和綁定句柄和定義句柄定義句柄是由是由 OCI 庫隱式分配的庫隱式分配的 不需要用戶分配 不需要用戶分配 圖 2 2 顯示了不同類型的句柄的層次 圖圖 2 2 句柄的層次句柄的層次 環(huán)境句柄是由 OCIEnvCreate 或者 OCIEnvNlsCreate 函數(shù)分配和初始化的 所有的 OCI 程序都需要執(zhí)行它們中的任一個(gè) 所有的用戶分配的句柄都通過 OCI 句柄分配函數(shù)來初始化 即 OCIHandleAlloc 函數(shù) 句柄類型包括 線程句柄 描述句柄 語句句柄 服務(wù)上下文句柄 錯(cuò)誤句柄和服務(wù)器 句柄等 線程句柄通過 OCIThreadHndInit 函數(shù)分配 一個(gè)應(yīng)用程序必須釋放所有的不再使用的句柄 OCIHandleFree 函數(shù)釋放所有的句柄 注意 注意 當(dāng)一個(gè)父句柄被釋放后當(dāng)一個(gè)父句柄被釋放后 所有 所有與之相連與之相連的子句柄的子句柄也被釋放也被釋放并且再也不能被使用 并且再也不能被使用 例如 當(dāng)一個(gè)語句句柄釋放后 例如 當(dāng)一個(gè)語句句柄釋放后 任何任何與之相與之相連的連的綁定和定義句柄綁定和定義句柄也都被釋放 也都被釋放 句柄減少了對全局變量的需要 句柄也使錯(cuò)誤報(bào)告更容易 一個(gè)錯(cuò)誤句柄用來返回錯(cuò)誤 和診斷信息 2 3 1 環(huán)境句柄環(huán)境句柄 環(huán)境句柄提供了一個(gè)所有的 OCI 函數(shù)被調(diào)用的上下文 每一個(gè)環(huán)境句柄包含一個(gè)支持快 速訪問的內(nèi)存緩存 所有的環(huán)境句柄下的內(nèi)存分配都是通過這個(gè)緩存完成的 如果多個(gè)線程 想要在同一個(gè)環(huán)境句柄下分配內(nèi)存 則它們對緩存的訪問是序列化的 當(dāng)多個(gè)線程共享一個(gè) 單獨(dú)的環(huán)境句柄時(shí) 它們會(huì)阻塞對緩存的訪問 環(huán)境句柄作為 OCIHandleAlloc 函數(shù)的 parent 參數(shù)來分配其他句柄類型 綁定句柄和定 義句柄是隱式分配的 2 3 2 錯(cuò)誤句柄錯(cuò)誤句柄 錯(cuò)誤句柄作為一個(gè)參數(shù)傳遞至大多數(shù) OCI 函數(shù) 錯(cuò)誤句柄維持著關(guān)于一個(gè) OCI 操作中所 發(fā)生的錯(cuò)誤的信息 如果一個(gè)函數(shù)調(diào)用中發(fā)生了一個(gè)錯(cuò)誤 錯(cuò)誤句柄可以傳給 OCIErrorGet 函數(shù)來獲取關(guān)于那個(gè)錯(cuò)誤的額外信息 由于大多數(shù) OCI 函數(shù)都需要一個(gè)錯(cuò)誤句柄作為一個(gè)參數(shù) 分配錯(cuò)誤句柄是一個(gè) OCI 應(yīng)用 程序中的前幾個(gè)步驟之一 2 3 3 服務(wù)上下文句柄和服務(wù)上下文句柄和相關(guān)相關(guān)的句柄的句柄 一個(gè)服務(wù)上下文句柄定義了決定 OCI 調(diào)用的上下文的屬性 服務(wù)上下午句柄包含 3 個(gè)句 柄作為它的屬性 分別代表一個(gè)服務(wù)器連接 一個(gè)用戶會(huì)話和一個(gè)事務(wù) 圖 2 3 列出了這些 屬性 圖圖 2 3 一個(gè)服務(wù)器句柄 Server Handle 識別對一個(gè)數(shù)據(jù)庫的連接 一個(gè)用戶會(huì)話句柄 User Session Handle 定義了一個(gè)用戶的角色和權(quán)限以及函數(shù)執(zhí)行 的操作上下文 一個(gè)事務(wù)句柄定義了 SQL 操作所屬的事務(wù) 在需要更復(fù)雜的會(huì)話管理的應(yīng)用程序中 服務(wù)上下午句柄必須被顯式地分配 并且服務(wù) 器句柄和用戶會(huì)話句柄必須通過 OCIAttrSet 函數(shù)被顯式地設(shè)置到服務(wù)上下午句柄中 OCIServerAttach 函數(shù)和 OCISessionBegin 函數(shù)分別初始化服務(wù)器和用戶會(huì)話句柄 當(dāng)應(yīng)用程序?qū)?shù)據(jù)庫做修改時(shí) OCI 自動(dòng)隱式分配的事務(wù)句柄正確地工作 2 3 4 語句句柄 綁定句柄和語句句柄 綁定句柄和定義句柄定義句柄 一個(gè)語句句柄是識別 SQL 或者 PL SQL 語句以及與之相連的屬性的上下文 如圖 2 4 所 示 圖圖 2 4 關(guān)于輸入綁定變量和輸出綁定變量的信息儲(chǔ)存于綁定句柄中 bind handle OCI 庫為每一 個(gè)與 OCIBindByName 函數(shù)或者 OCIBindByPos 函數(shù)相連的占位符分配一個(gè)綁定句柄 用戶一 定不可以分配綁定句柄 它們是由綁定函數(shù)隱式分配的 查詢返回的數(shù)據(jù)根據(jù)定義句柄 define handle 的描述來轉(zhuǎn)換和獲取 OCI 庫為每一個(gè) OCIDefineByPos 函數(shù)中所定義的輸出變量分配一個(gè)定義句柄 用戶一定不可以分配定義句 柄 它們是由定義函數(shù)隱式分配的 綁定句柄和定義句柄是由 OCI 庫顯式分配的 并且如果綁定或者定義操作是重復(fù)的話 綁定句柄和定義句柄是被重復(fù)使用的 當(dāng)語句句柄被釋放或者當(dāng)一個(gè)新的語句被準(zhǔn)備到語句 句柄上后 綁定句柄或者定義句柄就被釋放 顯式分配綁定或者定義句柄可能導(dǎo)致內(nèi)存泄露 顯式釋放綁定句柄或者定義句柄可能導(dǎo)致程序異常終止 2 3 5 描述句柄描述句柄 描述句柄 describe handle 由 OCI 描述函數(shù)所使用 OCIDescribeAny 這個(gè)函數(shù)獲取關(guān)于 數(shù)據(jù)庫中的數(shù)據(jù)庫對象的信息 例如 函數(shù)或者過程 這個(gè)函數(shù)有一個(gè)參數(shù)是描述句柄 以及 關(guān)于被描述的對象的附加信息 當(dāng)函數(shù)執(zhí)行完成后 描述句柄就存有關(guān)于那個(gè)對象的信息 然后 OCI 應(yīng)用程序可以通過參數(shù)描述符的屬性獲取描述信息 2 3 6 句柄屬性句柄屬性 所有的 OCI 句柄都有表示存儲(chǔ)在那個(gè)句柄中的數(shù)據(jù)的屬性 我們可以通過屬性獲取函 數(shù) OCIAttrGet 來獲取句柄屬性值 并且我們可以通過 OCIAttrSet 函數(shù)來設(shè)置句柄的屬性值 例如 下面的代碼顯示了通過寫入會(huì)話句柄的 OCI ATTR USERNAME 屬性來設(shè)置會(huì)話句 柄中的用戶名 text username hr err OCIAttrSet dvoid mysessp OCI HTYPE SESSION dvoid username ub4 strlen char username OCI ATTR USERNAME OCIError myerrhp 一些 OCI 函數(shù)要求在這些函數(shù)被調(diào)用前 一些特定的句柄屬性值被設(shè)置 例如 調(diào)用 OCISessionBegin 函數(shù)來設(shè)置用戶的登錄會(huì)話 在這個(gè)函數(shù)被調(diào)用之前 必須設(shè)置用戶會(huì)話 句柄的用戶名和密碼屬性 其他的 OCI 函數(shù)執(zhí)行完成后 會(huì)在句柄屬性中提供有用的返回?cái)?shù)據(jù) 例如 當(dāng) OCIStmtExecute 函數(shù)被調(diào)用來執(zhí)行 SQL 查詢時(shí) 關(guān)于所選字段的描述信息被返回到語句句 柄中 ub4 parmcnt 獲取選擇列表中的字段數(shù)量 Err OCIAttrGet dvoid stmhp ub4 OCI HTYPE STMT dvoid 2 3 7 OCI 描述符描述符 OCI 描述符 descriptor 和定位符 locator 是維護(hù)特殊數(shù)據(jù)信息的不透明數(shù)據(jù)結(jié)構(gòu) 表 2 2 列出了它們以及對應(yīng)的 C 數(shù)據(jù)結(jié)構(gòu)和還有在 OCIDescriptorAlloc 函數(shù)中所用到的 OCI 類型常 量 OCIDescriptorFree 函數(shù)釋放描述符和定位符 表表 2 2 下面描述了各種描述符類型的主要目的 OCISnapshot 用于語句執(zhí)行 OCILobLocator 用于 LOB OCI DTYPE LOB 或者 BFILE OCI DTYPE FILE 函數(shù) OCIParam 用于描述函數(shù) OCIRowid 用于綁定或者定義 ROWID 值 2 3 7 12 3 7 1 LOBLOB 和和 BFILE BFILE 定位符定位符 一個(gè)大對象 LOB 是保存二進(jìn)制大數(shù)據(jù)或者字符大對象 CLOB 數(shù) 據(jù)的 Oracle 數(shù)據(jù)類型 在數(shù)據(jù)庫中 一個(gè)不透明的叫做 LOB 定位符的數(shù)據(jù)結(jié)構(gòu)保存在一個(gè) 數(shù)據(jù)庫行的 LOB 字段中 定位符作為實(shí)際 LOB 值的指針 實(shí)際的 LOB 值保存在其他的地方 OCI LOB 定位符用于對 LOB BLOB 或者 CLOB 類型或者 FILE BFILE 類型進(jìn)行 OCI 操作 OCILobXXX 函數(shù)使用 LOB 定位符作為參數(shù)而不是 LOB 數(shù)值 OCI LOB 函數(shù)不使用實(shí)際的 LOB 數(shù)據(jù)作為參數(shù) 它們使用 LOB 定位符作為參數(shù)并且通過引用它們來操作 LOB 數(shù)據(jù) 通過向 OCIDescriptorAlloc 函數(shù)傳遞 OCI DTYPE LOB 作為類型參數(shù)來為 BLOBs 或者 CLOBs 分配 LOB 定位符 傳遞 OCI DTYPE FILE 作為類型參數(shù)為 BFILEs 分配 LOB 定位符 注意 注意 這兩種這兩種 LOBLOB 定位符類型是不能互換的 定位符類型是不能互換的 當(dāng)綁定或者定義一個(gè)當(dāng)綁定或者定義一個(gè) BLOBBLOB 或者或者 CLOBCLOB 時(shí) 時(shí) 應(yīng)用程序必須注意應(yīng)用程序必須注意定位符是否是通過定位符是否是通過 OCI DTYPE LOBOCI DTYPE LOB 分配的 同樣 當(dāng)綁定或者分配的 同樣 當(dāng)綁定或者定義一個(gè)定義一個(gè) BFILEBFILE 時(shí) 時(shí) 應(yīng)用程序必須應(yīng)用程序必須確保確保使用使用 OCI DTYPE FILEOCI DTYPE FILE 分配定位符 分配定位符 一個(gè) OCI 應(yīng)用程序可以使用一個(gè)包含有 LOB 字段或者屬性的 SQL 語句從 Oracle 數(shù)據(jù)庫 獲取 LOB 定位符 這種情況下 應(yīng)用程序需要首先分配 LBO 定位符然后用它來定義一個(gè)輸出 變量 與此類似 一個(gè) LOB 定位符可以被用來作為綁定操作的一部分以創(chuàng)建一個(gè) LOB 和一個(gè) SQL 語句中的占位符的聯(lián)結(jié) 2 3 7 22 3 7 2 參數(shù)描述符參數(shù)描述符 OCI 應(yīng)用程序使用參數(shù)描述符獲取關(guān)于所選字段或者數(shù)據(jù)庫對象的信息 通過描述操 作獲取這種信息 參數(shù)描述符是唯一的不通過 OCIDescriptorAlloc 函數(shù)分配的描述符 我們只有通過 描述句柄 語句句柄或者復(fù)雜對象獲取句柄來獲取它 使用 OCIParamGet 函數(shù) 3 OCI 編程步驟編程步驟 下面描述開發(fā)一個(gè) OCI 應(yīng)用程序的細(xì)節(jié) 3 1 OCI 環(huán)境初始化環(huán)境初始化 這部分描述如何初始化 OCI 環(huán)境 設(shè)立一個(gè)服務(wù)器的連接 并且授權(quán)一個(gè)用戶對數(shù)據(jù)庫 執(zhí)行操作 首先 初始化 OCI 環(huán)境時(shí)有三個(gè)主要步驟 創(chuàng)建創(chuàng)建 OCI 環(huán)境環(huán)境 分配句柄和描述符分配句柄和描述符 應(yīng)用程序初始化應(yīng)用程序初始化 連接和創(chuàng)建會(huì)話 連接和創(chuàng)建會(huì)話 3 1 13 1 1 創(chuàng)建創(chuàng)建 OCIOCI 環(huán)境環(huán)境 每一個(gè) OCI 函數(shù)調(diào)用都是在 OCIEnvCreate 函數(shù)所創(chuàng)建的環(huán)境中執(zhí)行的 這個(gè)函數(shù)必 須在其他 OCI 函數(shù)執(zhí)行前被調(diào)用 唯一的例外是設(shè)置 OCI 共享模式的進(jìn)程級屬性 OCIEnvCreate 函數(shù)的模式 mode 參數(shù)指定應(yīng)用程序是否能夠 運(yùn)行在多線程環(huán)境中 mode OCI THREADED 使用對象 mode OCI OBJECT Use the AQ subscription registration 程序也可以選擇不使用這些模式而使用默認(rèn)模式 mode OCI DEFAULT 或者它們的聯(lián)合 使用垂直條 將它們分開 例如 如果 mode OCI THREADED OCI OBJECT 然后應(yīng)用程序 運(yùn)行在多線程環(huán)境中并且使用對象 我們可以為每個(gè) OCI 環(huán)境指明用戶定義的內(nèi)存管理函數(shù) 3 1 2 3 1 2 分配句柄和描述符分配句柄和描述符 Oracle 數(shù)據(jù)庫提供了用于分配和釋放句柄及描述符的 OCI 函數(shù) 在向 OCI 函數(shù)傳遞句 柄之前我們必須使用OCIHandleAlloc 函數(shù)分配句柄 除非OCI函數(shù) 比如OCIBindByPos 自動(dòng)為我們分配句柄 我們使用 OCIHandleAlloc 函數(shù)來分配表 2 1 列出的句柄 3 1 3 3 1 3 應(yīng)用程序初始化 連接和創(chuàng)建會(huì)話應(yīng)用程序初始化 連接和創(chuàng)建會(huì)話 一個(gè)應(yīng)用程序必須調(diào)用 OCIEnvCreate 函數(shù)來初始化 OCI 環(huán)境句柄 沿著這一步 應(yīng)用程序有兩個(gè)選項(xiàng)來設(shè)置一個(gè)服務(wù)器連接和開始一個(gè)用戶會(huì)話 單用戶 單連接或者多會(huì)話多連接 注意 注意 應(yīng)該使用應(yīng)該使用 OCIEnvCreate OCIEnvCreate 函數(shù)函數(shù)而不是而不是 OCIInitialize OCIInitialize 函數(shù)和函數(shù)和 OCIEnvInit OCIEnvInit 函函 數(shù) 數(shù) OCIInitialize OCIInitialize 和和 OCIEnvInit OCIEnvInit 函數(shù)函數(shù)是向后兼容的函數(shù) 是向后兼容的函數(shù) 3 1 3 1 3 1 3 1 單用戶單用戶 單連接 單連接 如果應(yīng)用程序在任何時(shí)刻僅為各個(gè)數(shù)據(jù)庫連接維持一個(gè)單用戶會(huì)話 這個(gè)選項(xiàng)就是簡化 的登錄函數(shù) 當(dāng)一個(gè)應(yīng)用程序調(diào)用 OCILogon 函數(shù)時(shí) OCI 庫初始化傳遞給它的服務(wù)上下午句柄 并 且創(chuàng)建一個(gè)到用戶指定的數(shù)據(jù)庫的連接 下面的例子顯示了 OCILogon 函數(shù)的用法 OCILogon envhp errhp 這個(gè)函數(shù)的參數(shù)包括服務(wù)上下午句柄 它將被初始化 用戶名 用戶的密碼 還有用來 設(shè)置連接的數(shù)據(jù)庫名 這個(gè)函數(shù)會(huì)隱式地分配服務(wù)器句柄和用戶會(huì)話句柄 如果應(yīng)用程序使用這個(gè)登錄函數(shù) 則服務(wù)上下文句柄 服務(wù)器句柄和用戶會(huì)話句柄將成 為只讀的 應(yīng)用程序不能通過改變服務(wù)上下午句柄的相關(guān)屬性來轉(zhuǎn)換會(huì)話或事務(wù) 使用 OCILogon 函數(shù)初始化它的會(huì)話和認(rèn)證的應(yīng)用程序必須調(diào)用 OCILogoff 函數(shù)來 終止它們 3 1 3 2 3 1 3 2 多多會(huì)話會(huì)話或者多連接或者多連接 這個(gè)選項(xiàng)使用顯式的服務(wù)器連接和開始會(huì)話函數(shù)來維持一個(gè)數(shù)據(jù)庫連接之上的多用戶 會(huì)話和連接 服務(wù)器連接和開始會(huì)話的函數(shù)分別是 OCIServerAttach 創(chuàng)建一個(gè)到數(shù)據(jù)源執(zhí)行 OCI 操作的訪問路徑 OCISessionBegin 為一個(gè)用戶設(shè)置一個(gè)針對某一特定服務(wù)器的會(huì)話 為了在數(shù)據(jù) 庫服務(wù)器上執(zhí)行數(shù)據(jù)庫操作 必須執(zhí)行這個(gè)函數(shù) 這兩個(gè)函數(shù)設(shè)置一個(gè)能夠使我們執(zhí)行 SQL 或者 PL SQL 語句的執(zhí)行環(huán)境 3 1 43 1 4 在在 OCIOCI 中處理中處理 SQLSQL 語句語句 在 OCI 中處理 SQL 語句的細(xì)節(jié)在后面描述 3 2 提交或者回滾事務(wù)提交或者回滾事務(wù) 應(yīng)用程序通過調(diào)用 OCITransCommit 函數(shù)來提交對數(shù)據(jù)庫的修改 這個(gè)函數(shù)使用一 個(gè)服務(wù)上下文句柄作為它的一個(gè)參數(shù) 與此服務(wù)上下文句柄相連的事務(wù)將被提交 應(yīng)用程序 可以顯式地創(chuàng)建事務(wù)或者當(dāng)應(yīng)用程序修改數(shù)據(jù)庫時(shí)隱式地創(chuàng)建事務(wù) 注意 注意 如果如果使用使用 OCIOCIExecute Execute 函數(shù)函數(shù)的的 OCI COMMIT ON SUCCESSOCI COMMIT ON SUCCESS 模式模式 應(yīng)用程序應(yīng)用程序可以在可以在 每個(gè)語句執(zhí)行后選擇性地提交事務(wù) 這樣可以每個(gè)語句執(zhí)行后選擇性地提交事務(wù) 這樣可以節(jié)省一個(gè)額外的節(jié)省一個(gè)額外的網(wǎng)絡(luò)網(wǎng)絡(luò)開銷開銷 使用 OCITransRollback 函數(shù)來回滾事務(wù) 如果一個(gè)應(yīng)用程序以非正常方式同 Oracle 斷開連接 比如網(wǎng)絡(luò)連接斷開 并且 OCITransCommit 函數(shù)沒有被調(diào)用 則所有活動(dòng)的事務(wù)都會(huì)被自動(dòng)回滾 3 3 終止應(yīng)用程序終止應(yīng)用程序 一個(gè) OCI 程序需要在它終止前執(zhí)行如下步驟 1 調(diào)用 OCISessionEnd 函數(shù)刪除每一個(gè)會(huì)話的用戶會(huì)話 2 調(diào)用 OCIServerDetach 函數(shù)刪除每一個(gè)數(shù)據(jù)源的訪問 3 調(diào)用 OCIHandleFree 函數(shù)來釋放每一個(gè)句柄 4 刪除環(huán)境句柄 環(huán)境句柄會(huì)釋放所有與之相連的句柄 注意 注意 當(dāng)一個(gè)父句柄當(dāng)一個(gè)父句柄被釋放后 被釋放后 任何與其相連的任何與其相連的句句柄都會(huì)被自動(dòng)釋放 柄都會(huì)被自動(dòng)釋放 對 OCIServerDetach 函數(shù)和 OCISessionEnd 函數(shù)的調(diào)用不是必須的 但是建議進(jìn)行調(diào)用 如果應(yīng)用程序終止并且沒有調(diào)用 OCITransCommit 函數(shù)沒有被調(diào)用 則任何之前的事務(wù)都會(huì) 被自動(dòng)回滾 3 4 OCI 中的錯(cuò)誤處理中的錯(cuò)誤處理 OCI 函數(shù)有一個(gè)返回代碼集合 表 2 3 列出了 OCI 返回代碼 這些返回代碼指出了函數(shù) 的成功或者失敗 比如 OCI SUCCESS 或者 OCI ERROR 或者應(yīng)用程序需要的其他信息 比如 OCI NEED DATA 或者 OCI STILL EXECUTING 大多數(shù) OCI 函數(shù)會(huì)返回這些返回代碼中的一個(gè) 表表 2 3 OCI 返回代碼返回代碼 如果返回代碼提示發(fā)生了一個(gè)錯(cuò)誤 應(yīng)用程序可以調(diào)用 OCIErrorGet 函數(shù)來獲取 Oracle 的錯(cuò)誤代碼和信息 OCIErrorGet 函數(shù)的一個(gè)參數(shù)是引起錯(cuò)誤的錯(cuò)誤句柄 數(shù)據(jù)的返回代碼和錯(cuò)誤代碼數(shù)據(jù)的返回代碼和錯(cuò)誤代碼 表 2 4 列出了當(dāng)數(shù)據(jù)獲取時(shí)正常 為空或者被截短時(shí)的 OCI 返回代碼 錯(cuò)誤號碼 指示 器變量和字段返回代碼 表表 2 4 返回和錯(cuò)我代碼返回和錯(cuò)我代碼 3 5 編碼建議編碼建議 Coding Guidelines 這部分描述編寫 OCI 應(yīng)用程序時(shí) 一些附加的問題 3 5 1 參數(shù)類型參數(shù)類型 Parameter Types OCI 函數(shù)使用很多不同類型的參數(shù) 包括整數(shù) 句柄和字符串 地址參數(shù)地址參數(shù) Address Parameters 地址參數(shù)用來將變量的地址傳遞至 Oracle 服務(wù)器 整型參數(shù)整型參數(shù) Integer Parameters 二進(jìn)制整數(shù)和短的二進(jìn)制整型參數(shù)的大小依賴于系統(tǒng) 字符串參數(shù)字符串參數(shù) Character String Parameters 字符串參數(shù)是一種特殊類型的地址參數(shù) 每個(gè)需要一個(gè)字符串參數(shù)的 OCI 函數(shù)都需要一 個(gè)字符串長度參數(shù) 設(shè)置設(shè)置一個(gè)字段一個(gè)字段值為空值為空 Inserting Nulls into a Column 我們可以有多種方式向一個(gè)數(shù)據(jù)庫字段中插入空值 1 在 INSERT 或者 UPDATE 語句中使用 NULL 例如 下面的 SQL 語句 INSERT INTO emp ename empno deptno VALUES NULL 8010 20 會(huì)使 ENAME 字段為 NULL 2 在 OCI 綁定函數(shù)中使用指示器變量 3 5 2 指示器變量指示器變量 Indicator Variables 每一個(gè)定義和綁定OCI函數(shù)都有一個(gè)參數(shù)與一個(gè)指示器變量相連或者一個(gè)指示器變量數(shù) 組相連 C 語言沒有 NULL 值的概念 因此我們將一個(gè)輸入變量 input variable 聯(lián)系到指示器變量 indicator variable 來指明占位符 place holder 是否為 NULL 值 當(dāng)數(shù)據(jù)傳到 Oracle 時(shí) 這些指 示器變量的值決定一個(gè)數(shù)據(jù)庫字段是否被設(shè)為空值 對于輸出變量 output variable 指示器變量指示 Oracle 返回的值是否為 NULL 或者被截 短 在 OCIStmtFetch 函數(shù)獲取到 NULL 或者 OCIStmtExecute 函數(shù)執(zhí)行時(shí)出現(xiàn) truncation 時(shí) OCI 函數(shù)返回 OCI SUCCESS 輸出指示器變量被賦值 指示器變量的類型是 sb2 在指示器變量數(shù)組中 單獨(dú)的指示器元素為 sb2 類型 3 5 2 1 輸入輸入 Input 對于輸入宿主變量 OCI 應(yīng)用程序可以像指示器變量賦予如下值 表表 3 5 輸入指示器變量輸入指示器變量值值 Input Indicator Values 當(dāng)指示器變量值為 1 時(shí) Oracle 忽略輸入變量的值 將字段值設(shè)置為 NULL 當(dāng)指示器變量值大于等于 0 時(shí) Oracle 將指示器變量的值賦給字段 3 5 2 2 輸出輸出 Output 輸出時(shí) Oracle 可以賦予指示器變量如下值 表表 3 6 輸出指示器變量值輸出指示器變量值 Output Indicator Values 指示器變量值為 2 時(shí) 字段值的長度大于輸出變量的長度 字段值被截短 另外 字 段值的原始長度大于 sb2 類型的指示器變量所能保存的最大數(shù)值 指示器變量值為 1 時(shí) 所選字段的值為 NULL 并且輸出變量的值不變 指示器變量值為 0 時(shí) Oracle 將完整的字段值賦給了宿主變量 指示器變量值大于 0 時(shí) 字段值的長度大于輸出變量的長度 字段被截短 指示器變量 中返回的正數(shù)是字段值被截短前的真實(shí)長度 3 6 4 數(shù)據(jù)類數(shù)據(jù)類型型 這部分介紹 OCI 應(yīng)用程序中使用的 Oracle 外部數(shù)據(jù)類型的參考 也討論 Oracle 數(shù)據(jù)類型 以及當(dāng)我們的應(yīng)用程序和 Oracle 傳遞數(shù)據(jù)時(shí)繁盛的內(nèi)部數(shù)據(jù)類型和外部數(shù)據(jù)類型之間的轉(zhuǎn) 換 4 1 Oracle 數(shù)據(jù)類型數(shù)據(jù)類型 一個(gè)OCI程序的主要目的之一就是同一個(gè)Oracle服務(wù)器通信 OCI應(yīng)用程序可以通過SQL SELECT 查詢從數(shù)據(jù)庫表中獲取數(shù)據(jù) 或者通過 INSERT UPDATE 或者 DELETE 語句修改表中 的數(shù)據(jù) 在數(shù)據(jù)庫內(nèi)部 值保存在表的字段中 在內(nèi)部 Oracle 通過特定格式的內(nèi)部數(shù)據(jù)類型 internal datatypes 來表示數(shù)據(jù) 內(nèi)部數(shù)據(jù)類型包括 NUMBER CHAR 和 DATE 通常 OCI 應(yīng)用程序不與數(shù)據(jù)的內(nèi)部數(shù)據(jù)類型工作 而是與宿主主演預(yù)先定義的數(shù)據(jù)類 型工作 當(dāng)數(shù)據(jù)在 OCI 應(yīng)用程序和數(shù)據(jù)庫表中傳遞時(shí) OCI 庫在內(nèi)部數(shù)據(jù)類型和外部數(shù)據(jù)類 型之間進(jìn)行轉(zhuǎn)換 外部數(shù)據(jù)類型 external datatypes 是宿主語言在 OCI 頭文件中定義的數(shù)據(jù)類型 當(dāng)一個(gè) OCI 應(yīng)用程序綁定輸入變量時(shí) 綁定參數(shù)中有一個(gè)參數(shù)用來說明變量的外部數(shù)據(jù)類型代碼 SQLT 代碼 同樣地 當(dāng)定義調(diào)用中指明輸出變量時(shí) 必須說明獲取到的數(shù)據(jù)的外部表示 OCI 可以進(jìn)行大范圍的 Oracle 和 OCI 應(yīng)用程序間的數(shù)據(jù)類型轉(zhuǎn)換 OCI 外部數(shù)據(jù)類型多 于 Oracle 內(nèi)部數(shù)據(jù)類型 4 1 1 使用外部數(shù)據(jù)類型代碼使用外部數(shù)據(jù)類型代碼 External Datatype Codes 外部數(shù)據(jù)類型代碼告知 Oracle 我們應(yīng)用程序中的宿主變量被如何表示 這決定了當(dāng)數(shù) 據(jù)被返回到輸出變量時(shí) 如何進(jìn)行轉(zhuǎn)換或者輸入變量的數(shù)據(jù)如何轉(zhuǎn)換成 Oracle 的字段值 例如 如果我們想要將一個(gè) Oracle 字段中的 NUMBER 轉(zhuǎn)換成變長字符數(shù)組 我們需要在 OCIDefineByPos 函數(shù)中指定 VARCHAR2 外部數(shù)據(jù)類型代碼 為轉(zhuǎn)換綁定變量到一個(gè) Oracle 字段值 需要指明對應(yīng)于綁定變量的外部數(shù)據(jù)類型代碼 例如 如果我們想要輸入一個(gè)字符串比如 02 FEB 65 到一個(gè) DATE 字段 將數(shù)據(jù)類型指定為 字符串并且將長度參數(shù)設(shè)置為 9 4 2 內(nèi)部數(shù)據(jù)類型內(nèi)部數(shù)據(jù)類型 表 4 1 列出了 Oracle 的內(nèi)部數(shù)據(jù)類型 以及各個(gè)類型的最大內(nèi)部長度和類型代碼 表表 4 1 Oracle 內(nèi)部數(shù)據(jù)類型內(nèi)部數(shù)據(jù)類型 4 3 外部數(shù)據(jù)類型外部數(shù)據(jù)類型 表 4 2 列出了外部數(shù)據(jù)類型的類型代碼 為每一種數(shù)據(jù)類型 表中都列出了 Oracle 的內(nèi) 部數(shù)據(jù)被正常轉(zhuǎn)換為的 C 語言中的程序變量類型 表表 4 2 外部數(shù)據(jù)類型和代碼外部數(shù)據(jù)類型和代碼 4 3 1 VARCHAR2 VARCHAR2 數(shù)據(jù)類型是一個(gè)變長字符串 其最大長度為 4000 字節(jié) 輸入輸入 Input OCIBindByName 函數(shù)或者OCIBindByPos 函數(shù)中的value sz參數(shù)決定了可變長字符串的 長度 如果 value sz 參數(shù)大于 0 Oracle 從程序中的緩沖區(qū)地址開始讀取其所指定的字節(jié)數(shù) 如果 value sz 參數(shù)為 0 Oracle 將綁定變量看做 NULL 不考慮其真實(shí)內(nèi)容 如果我們向一個(gè) 具有 NOT NULL 約束的字段插入 NULL 值 Oracle 會(huì)報(bào)錯(cuò) 并且改行不會(huì)被插入 輸出輸出 Output 在 OCIDefineByPos 函數(shù)的 value sz 參數(shù)中指定想要獲取的返回值的長度 如果 value sz 為 0 則沒有數(shù)據(jù)被返回 為檢測返回值是否為空或者字符截短是否發(fā)生 就要在 OCIDefineByPos 函數(shù)中使用指 示器變量參數(shù) 如果我們沒有指定指示器變量參數(shù)并且返回一個(gè)空值 獲取函數(shù)會(huì)返回錯(cuò)誤 代碼 OCI SUCCESS WITH INFO 4 3 2 STRING NULL 結(jié)尾的 String 格式類似于 VARCHAR2 格式 除了 string 格式會(huì)包含一個(gè) NULL 終止 符 這個(gè)數(shù)據(jù)類型對 C 語言非常有用 輸入輸入 Input 如果 NULL 終止符沒有在指定的長度中發(fā)現(xiàn) Oracle 會(huì)產(chǎn)生如下錯(cuò)誤 ORA 01480 trailing NULL missing from STR bind value 如果沒有指定長度 則 OCI 使用隱含的最大長度 4000 輸出輸出 Output 在被返回的最后一個(gè)字符后面添加一個(gè) NULL 終止符 如果字符串超出了指定的字段長 度 則其會(huì)被截短并且輸出變量的最后一個(gè)字符包含 NULL 終止符 4 3 3 DATE Date 以二進(jìn)制格式保存 包含 7 個(gè)字節(jié) 如表 4 3 所示 表表 4 3 Data 數(shù)據(jù)類型的格式數(shù)據(jù)類型的格式 4 3 4 LOB 定位符定位符 Locator 當(dāng)一個(gè) OCI 應(yīng)用程序發(fā)出的 SQL 查詢中包括一個(gè) LOB 字段時(shí) 查詢返回的是 LOB 定位 符 而不是實(shí)際的 LOB 字段值 在 OCI 中 LOB 定位符映射 OCILobLocator 類型的變量 OCI 中的 LOB 相關(guān)函數(shù)使用一個(gè) LOB 定位符作為它們的參數(shù) 這些 OCI 函數(shù)假定 LOB 定 位符已經(jīng)被創(chuàng)建 不論其指向的 LOB 是否含有數(shù)據(jù) 綁定操作和定義操作都是對 LOB 定位符進(jìn)行操作 通過 OCIDescriptorAlloc 函數(shù)來分配 LOB 定位符 綁定和定義 LOB 的數(shù)據(jù)類型代碼如下 SQLT BLOB 一個(gè)二進(jìn)制 LOB 數(shù)據(jù)類型 SQLT CLOB 一個(gè)字符型 LOB 數(shù)據(jù)類型 5 在在 OCI 程序中使用程序中使用 SQL 語句語句 這一節(jié)討論使用 OCI 處理 SQL 語句是所涉及的概念和步驟 5 1 SQL 語句處理概要語句處理概要 一個(gè) OCI 程序的通常任務(wù)就是接受和處理 SQL 語句 這部分概述一下 SQL 處理中所涉及 的步驟 一旦我們分配了必要的句柄并且連接至服務(wù)器 按照圖 5 1 中的步驟來處理 SQL 語句 圖圖 5 1 處理處理 SQL 語句的步驟語句的步驟 1 準(zhǔn)備語句 使用 OCIStmtPrepare 函數(shù)或者 OCIStmtPrepare2 函數(shù)來定義一個(gè)應(yīng)用程 序請求 2 如果有必要的話 需要綁定占位符 對于 DML 語句和有輸入變量的查詢 要執(zhí)行 使用以下的函數(shù)執(zhí)行一個(gè)或者多個(gè)綁定 OCIBindByPos OCIBindByName OCIBindObject OCIBindDynamic OCIBindArrayOfStruct 3 也可以使用 OCIStmtPrepare2 函數(shù)來準(zhǔn)備一個(gè)語句進(jìn)行執(zhí)行 OCIStmtPrepare2 函 數(shù)是 OCIStmtPrepare 函數(shù)的增強(qiáng)版 其引入了對語句緩存的支持 4 執(zhí)行 調(diào)用 OCIStmtExecute 函數(shù)來執(zhí)行語句 對于 DDL 語句則不需要其他步驟 5 如有必要 需要進(jìn)行描述 如有必要使用 OCIParamGet 函數(shù)和 OCIAttrGet 函數(shù)來 描述所選字段 這是一個(gè)可選步驟 6 如有必要 需要進(jìn)行定義 對于查詢 執(zhí)行一個(gè)或者多個(gè) OCIDefineByPos OCIDefineObject OCIDefineDynamic 或者 OCIDefineArrayOfStruct 函數(shù)來為 SQL 語 句中的各個(gè)所選字段定義輸出變量 7 如有必要 需要進(jìn)行獲取操作 對于查詢 調(diào)用 OCIStmtFetch 來獲取查詢的結(jié)果 按照這些步驟 應(yīng)用程序可以釋放已經(jīng)分配的句柄 然后斷開同服務(wù)器的連接 或者處 理另外的 SQL 語句 5 2 準(zhǔn)備語句準(zhǔn)備語句 通過使用語句準(zhǔn)備函數(shù)和任何必要的綁定函數(shù) SQL 和 PL SQL 語句為執(zhí)行做好準(zhǔn)備 應(yīng)用程序指明一個(gè) SQL 或者 PL SQL 語句并且將語句中的占位符綁定至執(zhí)行是所用的數(shù)據(jù) 客戶端庫為準(zhǔn)備的語句分配空間 一個(gè)應(yīng)用程序調(diào)用OCIStmtPrepare 函數(shù)來請求一個(gè)SQL或者PL SQL語句為執(zhí)行做準(zhǔn)備 并且向其傳遞一個(gè)之前分配的語句句柄 這是一個(gè)本地調(diào)用 不需要同服務(wù)器的通訊 此時(shí) 在語句和特定的服務(wù)器間沒有聯(lián)結(jié) 在在 OCI 中綁定占位符中綁定占位符 大多數(shù) DML 語句 以及一些查詢 比如那些帶有 Where 子句的 需要程序?qū)?SQL 或者 PL SQL 中的一部分?jǐn)?shù)據(jù)傳遞給 Oracle 這個(gè)數(shù)據(jù)可以使常量或者字符串 在我們的程序編譯 時(shí)已經(jīng)是已知的 例如 下面的項(xiàng)數(shù)據(jù)庫中增加一條員工記錄的 SQL 語句 INSERT INTO emp VALUE 2365 BESTRY PROGRAMER 2000 20 5 3 執(zhí)行語句執(zhí)行語句 一個(gè) OCI 應(yīng)用程序通過調(diào)用 OCIStmtExecute 函數(shù)來執(zhí)行已經(jīng)準(zhǔn)備好的語句 當(dāng)一個(gè) OCI 應(yīng)用程序執(zhí)行查詢時(shí) 它從數(shù)據(jù)庫中獲取那些符合查詢條件的數(shù)據(jù) 在數(shù)據(jù) 庫內(nèi)部 數(shù)據(jù)以 Oracle 定義的格式儲(chǔ)存 當(dāng)結(jié)果返回后 OCI 應(yīng)用程序可以請求將數(shù)據(jù)轉(zhuǎn)換 成一種特定的宿主語言格式 并將其儲(chǔ)存在一個(gè)特定的輸出變量或者緩沖區(qū)中 對于查詢中的所選字段中的每一個(gè)字段 OCI 程序都必須定義一個(gè)接收查詢到的結(jié)果的 輸出變量 定義步驟說明了緩沖區(qū)的地址和將要獲取到的數(shù)據(jù)的類型 注意 注意 如果如果一個(gè)一個(gè) SELECT 語句語句的的輸出變量輸出變量在在調(diào)用調(diào)用 OCIStmtExecute 函數(shù)前函數(shù)前進(jìn)行了定義進(jìn)行了定義 OCIStmtExecute 函數(shù)函數(shù)中的中的 iters 參數(shù)參數(shù)指明的行數(shù)指明的行數(shù)將會(huì)直接將會(huì)直接獲取到已經(jīng)定義的獲取到已經(jīng)定義的輸出緩沖區(qū)中輸出緩沖區(qū)中 并且并且等于等于預(yù)獲取行數(shù)的預(yù)獲取行數(shù)的其他行其他行會(huì)被預(yù)獲取到 會(huì)被預(yù)獲取到 如果沒有其他行 如果沒有其他行 則不需要?jiǎng)t不需要調(diào)用調(diào)用OCIStmtFetch 就可以就可以完成獲取操作 完成獲取操作 5 4 獲取查詢結(jié)果獲取查詢結(jié)果 如果一個(gè) OCI 應(yīng)用程序已經(jīng)處理了一個(gè)查詢 通常會(huì)在語句執(zhí)行完成后調(diào)用 OCIStmtFetch 函數(shù)或者 OCIStmtFetch2 函數(shù)來獲取查詢結(jié)果 Oracle 鼓勵(lì)使用支持可滾動(dòng)游 標(biāo) scrollable cursors 的 OCIStmtFetch2 函數(shù) 獲取到的數(shù)據(jù)被放置到已經(jīng)在定義操作中指明的輸出變量中 6 綁定和定義操作綁定和定義操作 6 1 OCI 中的綁定概述中的綁定概述 本小節(jié)擴(kuò)展綁定和定義的基本概念 并且提供我們在 OCI 應(yīng)用程序中可以使用的綁定和 定義操作的更詳細(xì)的信息 另外 本節(jié)將討論結(jié)構(gòu)體數(shù)組的使用 以及其他的設(shè)計(jì)綁定 定 義和字符轉(zhuǎn)換的議題 例如 如下 INSERT 語句 INSERT INTO emp VALUES empno ename job sal deptno 還有如下變量聲明 text ename job sword empno sal deptno 綁定步驟再占位符名字和程序變量之間建立結(jié)合 綁定也說明了程序變量的數(shù)據(jù)類型和 長度 如圖 6 1 所示 圖圖 6 1 使用使用 OCIBindByName 函數(shù)函數(shù)來結(jié)合來結(jié)合占位符和占位符和程序變量程序變量 如果我們只改變綁定變量的值 則沒有必要為了重新執(zhí)行語句而進(jìn)行重新綁定 因?yàn)榻?定是按引用綁定 只要變量地址和句柄地址保持不變 我們就可以重新執(zhí)行引用那個(gè)變量的 語句而不需進(jìn)行重新綁定 6 1 1 按名字綁定和按名字綁定和按位置綁定按位置綁定 上述例子是一個(gè)按名字綁定的例子 語句中的每個(gè)占位符都有一個(gè)名字與其相結(jié)合 比 如 ename 或者 sal 當(dāng)這個(gè)語句已經(jīng)準(zhǔn)備好并且占位符已經(jīng)和應(yīng)用程序中的一個(gè)變量值相結(jié) 合時(shí) 結(jié)合是通過 OCIBindByName 函數(shù)設(shè)立的 第二種綁定是按位置進(jìn)行綁定 在按位置綁定中 通過占位符在語句中的位置而不是名 字來進(jìn)行綁定 為了進(jìn)行綁定 使用 OCIBindByPos 函數(shù)對輸入值和占位符的位置建立結(jié)合 使用之前的例子進(jìn)行按位置綁定 INSERT INTO emp VALUES empno ename job sal deptno 這 5 個(gè)占位符分別通過調(diào)用 OCIBindByPos 函數(shù)進(jìn)行綁定 并且將占位符在語句中的位 置傳遞到 OCIBindByPos 函數(shù)的位置 position 參數(shù)中 例如 調(diào)用 OCIBindByPos 函數(shù)并傳遞 位置參數(shù) 1 empno 占位符將會(huì)被綁定 ename 則傳遞位置參數(shù) 2 在重復(fù)綁定的情況下 僅有一個(gè)單獨(dú)綁定調(diào)用是必要的 考慮如下的 SQL 語句 這個(gè) 語句查詢數(shù)據(jù)庫中提成和收入均大于某一數(shù)量的員工 SELECT empno FROM emp WHERE sal some value AND comm some value 通過調(diào)用一次 OCIBindByName 函數(shù)進(jìn)行按名字綁定 OCI 程序就可以完成該語句的綁 定操作 在這種情況下 第二個(gè)占位符繼承第一個(gè)占位符的綁定信息 6 1 2 OCI 綁定的步驟綁定的步驟 綁定占位符需要多個(gè)步驟 下面的例子顯示了綁定一個(gè) SQL 語句中的各個(gè)占位符的句 柄分配和綁定 通過調(diào)用 OCIStmtPrepare 函數(shù) 將 SQL 語句結(jié)合到 stmthp 語句句柄 text insert text INSERT INTO emp empno ename job sal deptno VALUES empno ename job sal deptno 綁定 SQL 語句中的占位符 每一個(gè)占位符都需要一個(gè)綁定句柄 checker errhp OCIBindByName stmthp checkerr errhp OCIBindByName stmthp checkerr errhp OCIBindByName stmthp checkerr errhp OCIBindByName stmthp checkerr errhp OCIBindByName stmthp 6 1 3 OCI 綁定綁定 LOBs 有兩種方式來綁定 LOBs 綁定 LOB 定位符 locator 而不是實(shí)際的 LOB 值 在這種情況下 LOB 數(shù)值是通過向 OCILOB 函數(shù)傳遞 LOB 定位符完成的 直接綁定 LOB 數(shù)值 而不是使用 LOB 定位符 綁定綁定 LOBLOB 定位符定位符 一個(gè)單獨(dú)的定位符或者一個(gè)定位符數(shù)組都可以在一個(gè)單獨(dú)的綁定調(diào)用中綁定 在這兩種 情況下 應(yīng)用程序必須傳遞 LOB 定位符的地址而不是定位符本身 例如 如果一個(gè)應(yīng)用程序 已經(jīng)準(zhǔn)備了一個(gè) SQL 語句 INSERT INTO some table VALUES one lob one lob 是一個(gè)與 LOB 字段對應(yīng)的綁定變量 并且已經(jīng)做出了如下聲明 OCILobLocator one lob 然后 下面的調(diào)用將會(huì)被用來綁定占位符和執(zhí)行語句 初始化單個(gè)定位符 One lob OCIDescriptorAlloc OCI DTYPE LOB 傳遞定位符的地址 OCIBindByName dvoid OCIStmtExecute 1 1 是迭代參數(shù) 在描述符可以使用之前 我們必須調(diào)用 OCIDescriptorAlloc 函數(shù)來分配描述符 6 2 OCI 定義概述定義概述 查詢語句將從數(shù)據(jù)庫中獲取的數(shù)據(jù)返回到我們的應(yīng)用程序中 當(dāng)處理一個(gè)查詢的時(shí)候 我們必須為所選字段中的每一個(gè)字段定義一個(gè)輸出變量 定義步驟決定了返回值儲(chǔ)存在什么 地方和以什么形式儲(chǔ)存 例如 如果我們的應(yīng)用程序處理如下語句 我們需要定義兩個(gè)輸出變量 一個(gè)用來接收 ename 字段返回的值 一個(gè)用來接收 ssn 字段返回的數(shù)值 SELECT name ssn FROM employess WHERE empno empnum 如果我們只對獲取 name 字段值感興趣 則我們可以不為 ssn 字段定義輸出變量 OCI 在客戶端本地處理定義調(diào)用 除了說明保存結(jié)果的緩沖區(qū)的位置 定義步驟還決定 了當(dāng)數(shù)據(jù)返回到應(yīng)用程序時(shí)如何進(jìn)行數(shù)據(jù)轉(zhuǎn)換 OCIDefineByPos 函數(shù)的 dty 參數(shù)說明輸出變量的數(shù)據(jù)類型 當(dāng)數(shù)據(jù)獲取至輸出變量時(shí) OCI 能夠執(zhí)行大范圍的數(shù)據(jù)轉(zhuǎn)換 例如 Oracle 的 DATE 類型的內(nèi)部數(shù)據(jù)可以自動(dòng)轉(zhuǎn)換為 String 數(shù)據(jù)類型 6 2 1 OCI 定義的步驟定義的步驟 通過調(diào)用 OCIDefineByPos 函數(shù)來完成基本的定義 這一步建立了所選字段和輸出變量 的結(jié)合 下面的例子顯示了在執(zhí)行完成后一個(gè)輸出變量被定義 SELECT department name FROM departments WHERE department id dept input 這個(gè)輸入變量已經(jīng)被綁定 并且其數(shù)據(jù)來自于下面的用戶輸入 Printf Enter employee dept Scanf d 執(zhí)行語句 如果 OCIStmtExecute 返回 OCI NO DATA 則表示沒有數(shù)據(jù)匹配該查詢 然后該部門號即為無效部門號 if status OCIStmtExecute svchp stmthp errhp 0 0 OCISnapshot 0 OCISnapshot 0 OCI DEFAULT return OCI ERROR if status OCI NO DATA printf The dept you entered doesn t exist n return 0 下面的語句描述所選字段dname 并且返回它的數(shù)據(jù)長度 checkerr errhp OCIParamGet dvoid stmthp ub4 OCI HTYPE STMT errhp dvoid checkerr errhp OCIAttrGet dvoid parmdp ub4 OCI DTYPE PARAM dvoid 使用返回的dname的長度來分配輸出緩沖區(qū) 并且定義輸出變量 如果定義函數(shù)返 回錯(cuò)誤則退出應(yīng)用程序 dept text malloc int deptlen 1 if status OCIDefineByPos stmthp return OCI ERROR 6 2 2 OCI 定義定義 LOB 輸出變量輸出變量 有兩種方式定義 LOBs 定義一個(gè) LOB 定位符 而不是真實(shí)的 LOB 數(shù)值 這種情況下 OCI LOB 函數(shù)通過 LOB 定位符來讀取或者寫入 LOB 數(shù)值 不使用 LOB 定位符 直接定義一個(gè) LOB 值 定義定義 LOB 定位符定位符 應(yīng)用程序必須傳遞 LOB 定位符的地址而不是定位符本身 例如 如果應(yīng)用程序已經(jīng)準(zhǔn) 備了下面的 SQL 語句 SELECT lob1 FROM some table 其中 lob1 是 LOB 字段并且 one lob 是對應(yīng)于 LOB 字段的定義變量 其聲明如下 OCILobLocator one lob 下面的步驟綁定
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024-2030年中國奢侈品箱包行業(yè)規(guī)模分析及投資策略研究報(bào)告
- 2024-2030年中國半纖維素酶行業(yè)運(yùn)行狀況及投資發(fā)展前景預(yù)測報(bào)告
- 2024年生產(chǎn)車間租賃與產(chǎn)業(yè)基金投資服務(wù)合同3篇
- 質(zhì)量監(jiān)督程序
- 詹凱煜畢業(yè)設(shè)計(jì)報(bào)告書論文
- 2024年度高層建筑基礎(chǔ)施工混凝土供應(yīng)合同范本3篇
- 海南省部分學(xué)校2021-2022學(xué)年高一上學(xué)期期中考試歷史試題
- 2024年城市宣傳片制作與發(fā)布合同范本3篇
- 2025年嘉峪關(guān)道路貨運(yùn)駕駛員從業(yè)資格證考試
- 2025投影系統(tǒng)設(shè)備購銷合同書
- 兵團(tuán)電大建筑結(jié)構(gòu)實(shí)訓(xùn)
- 愛吃糖的大獅子
- 醫(yī)學(xué)小常識幻燈片課件
- 化妝品功效評價(jià)
- 風(fēng)電場通用類作業(yè)行為風(fēng)險(xiǎn)管控清單
- 【幼兒園園本教研】幼兒表征的教師一對一傾聽策略
- GCS評分實(shí)施細(xì)則及要點(diǎn)說明課件
- 英語│英語中考英語閱讀理解(有難度)
- 手術(shù)操作分類代碼國家臨床版3.0
- 采血知情同意書模板
- 我的家鄉(xiāng)廣東廣州宣傳簡介
評論
0/150
提交評論