




已閱讀5頁,還剩7頁未讀, 繼續免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
此文檔收集于網絡,如有侵權,請聯系網站刪除DB2 靜態 SQL 和動態 SQL 的比較與實踐(轉)SQL 語言作為標準的查詢語言,幾乎被所有的數據庫管理系統 (DBMS) 所支持,并成為國際標準。標準的 SQL 語言一般包括三類,即 DDL (Data Definition Language, 數據描述語言 ) 、DML (Data Manipulation Language, 數據操縱語言 ) 和 DCL(Data Control Language,數據控制語言 )。通過這些標準的 SQL 語句,使得各種數據庫能以一種較為統一的方式被訪問。 DB2(本文以下專指 DB2 UDB for Linux, Unix 和 Windows 版本)允許用戶通過多種編程接口發送 SQL 語句到數據庫引擎,然后由引擎統一編譯并且運行。SQL 語句從編譯和運行的角度可以分為兩種,靜態 SQL和 動態 SQL,這兩種 SQL 在使用方式、運行機制和性能表現等方面各有特點 : 靜態 SQL:靜態 SQL 語句一般用于嵌入式 SQL 應用中,在程序運行前,SQL 語句必須是確定的,例如 SQL 語句中涉及的列名和表名必須是存在的。靜態 SQL 語句的編譯是在應用程序運行前進行的,編譯的結果會存儲在數據庫內部。而后程序運行時,數據庫將直接執行編譯好的 SQL 語句,降低運行時的開銷。 動態 SQL:動態 SQL 語句是在應用程序運行時被編譯和執行的,例如,使用 DB2 的交互式工具 CLP 訪問數據庫時,用戶輸入的 SQL 語句是不確定的,因此 SQL 語句只能被動態地編譯。動態 SQL 的應用較多,常見的 CLI 和 JDBC 應用程序都使用動態 SQL。 表 1列舉了靜態 SQL 和動態 SQL 的比較結果。 表 1. 靜態 SQL 和動態 SQL 的比較靜態 SQL動態 SQLSQL 語句直接嵌入到宿主編程語言,程序需要預編譯處理這些嵌入的 SQL 語句SQL 語句一般作為宿主語言的變量出現。嵌入式動態 SQL 應用需要預編譯,非嵌入式 SQL 應用則無需預編譯SQL 語句在程序被編譯時已知,涉及的數據庫對象已存在SQL 語句在程序被編譯時未知,涉及的數據庫對象可以是運行時才創建的SQL 語句在程序運行前被編譯SQL 語句在程序運行時被編譯SQL 語句的編譯結果在 DB2 的目錄 (catalog) 中持久化保存SQL 語句的編譯結果緩存在數據庫的內存里運行時僅讀取目錄 (catalog)運行時編譯 SQL 語句需對目錄 (catalog) 加鎖SQL 語句的優化是根據編譯時的數據庫統計信息進行的,不能完全反映運行時的情況SQL 語句的優化是根運行時的數據庫統計信息進行的對 SQL 語句所訪問的數據對象的權限檢查是在綁定時進行的對 SQL 語句所訪問的數據對象的權限檢查是在運行時進行的權限控制的粒度是包(package,一組 SQL 語句的編譯結果),用戶僅需要訪問包的權限權限控制的粒度是 SQL 語句,用戶需要具有訪問 SQL 語句中每個數據對象的權限如果 SQL 語句中的對象被修改,如 DDL 執行,整個包都需要重新綁定當 SQL 語句中的對象被修改時,僅執行過的語句在下次運行時需要重新編譯根據編程方法的不同,DB2 的應用程序開還可以分為嵌入式 SQL 編程和非嵌入式編程 : 嵌入式 SQL 編程將 SQL 語句嵌入到宿主語言 (host) 的程序中,例如 C/C+ 程序。因為宿主語言不識別 SQL 語句,先要對程序進行預編譯,把 SQL 語句轉變為對 DB2 服務的調用,并重寫源代碼,最后再使用宿主語言的編譯器對應用程序進行編譯。嵌入式 SQL 都需要被綁定到特定的數據庫中,可分為嵌入式靜態 SQL 和嵌入式動態 SQL。 非嵌入式應用程序不需要預編譯,且方法較多,如 CLI、JDBC、ODBC、ADO.NET 等等,這些方法中都使用動態 SQL。表 2列舉了常見的 DB2 編程接口。 表 2. DB2 的編程接口一覽編程接口靜態 / 動態是否為嵌入式嵌入式 SQL靜態和動態是DB2 CLI動態否SQLJ靜態是JDBC動態否ADO.NET,OLE DB動態否Perl DBI動態否PDO(PHP 數據對象 )動態否在下面的幾個章節中,我們將陸續從使用角度上描述靜態和動態 SQL 在各種編程接口中的應用,并運用一些實例來介紹在具體的場景中如何選擇。 靜態 SQL 應用嵌入式靜態 SQL無論是嵌入式靜態 SQL 還是嵌入式動態 SQL,都需要先進行預編譯,并綁定到特定的數據庫。DB2 的嵌入式 SQL 應用程序支持以下幾種語言:C,C+,COBOL,FORTRAN 和 REXX。 對嵌入式靜態 SQL 而言,只能使用編譯時確定的 SQL 語句和訪問編譯時已經存在的數據庫對象。清單 1是一個查詢表的例子,使用 C 語言 : 清單 1. 嵌入式靜態 SQL 的 C 語言片斷 /test.sqc EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; sqlint32 t_seq = 0; char t_name64=0; EXEC SQL END DECLARE SECTION; . t_seq = 5; EXEC SQL SELECT c_name INTO :t_name FROM test_tbl WHERE seq=:t_seq; printf(c_name = %s n, t_name);使用下面的命令,對上述代碼進行預編譯和編譯: 清單 2. 嵌入式靜態 SQL 的編譯命令 # 需要先連接數據庫 db2 connect to TESTDB # 使用 PREP 命令對 sqc 源文件進行預編譯,這將生成 test.c 源文件 db2 PREP test.sqc # 使用 C 編譯器對 test.c 進行編譯 xlC -q64 -I$DB2PATH/include -g -L$DB2PATH/lib -ldb2 -o test test.cSQLJSQLJ 是應用于靜態 SQL 的 Java 編程接口。使用 SQLJ 編寫應用程序和使用其他的語言接口相似,一個典型的 SQLJ 應用程序主要包括以下幾個方面: 載入包含 SQLJ 和 JDBC 的 Java 包。 定義收發數據的載體變量。 連接至數據庫,運行相應的 SQL 語句并且正確處理錯誤情況,最后從數據庫斷開。 清單 3是 SQLJ 中執行 SELECT 語句的代碼片斷。 清單 3. 簡單的 SQLJ 程序片斷 / 載入相關包 import sqlj.runtime.*; import java.sql.*; / 連接至數據庫 Connection con0 = DriverManager.getConnection(url); / 執行相關的 SQL 語句 #sql ctx iter = SELECT NAME FROM EMP; / 得到結果 while (iter.next() System.out.println(iter.LASTNAME(); 在 SQLJ 應用程序中,可以使用 ExecutionContext 類去控制和監控 SQL 語句的執行,如 清單 4所示。 清單 4. 在 SQLJ 使用 ExecutionContext / 分配存儲執行上下文的變量 ExecutionContext exeCtx=new ExecutionContext(); / 關聯變量和要執行的語句 #sql connCtx, exeCtx DELETE FROM EMP WHERE SALARY 10000; / 獲取結果 System.out.println(Deleted + exeCtx.getUpdateCount() + rows);動態 SQL 應用嵌入式動態 SQL與嵌入式靜態 SQL 相同,嵌入式動態 SQL 也需要預編譯。不同的是,嵌入式動態 SQL 將 SQL 語句存放在宿主語言的字符型變量中,這樣的 SQL 語句在預編譯時是不被處理的,而是被當作主機變量對待,直到程序運行時才被編譯執行。 得益于動態 SQL 的優點,嵌入式動態 SQL 可以處理運行時才確定的 SQL 語句,例如由程序運行時拼接的 SQL 語句。為了處理返回結果未知的 SELECT 語句,嵌入式動態 SQL 使用 SQLDA(SQL descriptor area) 結構和 DESCRIBE 語句獲取結果集的結構和屬性。SQLDA 結構如 圖 1所示。HEADER 描述整個結果集的信息,而每個 SQLVAR 結構描述結果集中一個字段的信息。 圖 1. SQLDA 結構清單 5展示了如何使用 SQLDA 結構和 DESCRIBE 語句處理 SELECT 語句。 清單 5. 使用 SQLDA 結構和 DESCRIBE 語句的偽代碼 /test1.sqc / 聲明兩個 SQLDA 指針,minsqlda 將是一個最小的 SQLDA 結構,用于 PREPARE 語句, / 此時結果集的字段數量未知,所以只需一個最小的 SQLDA,即包含 HEADER 和一個 SQLVAR struct sqlda * minsqlda = new sqlda; struct sqlda * fulsqlda = NULL; strcpy(hostVarStmt, SELECT name FROM TEST_TBL); / PREPARE 將填寫 minsqlda 的 header,sqldabc 為 SQLDA 總長度,sqln 為 SQLVAR 數量,即字段數量 EXEC SQL PREPARE STMT INTO :*minsqlda FROM :hostVarStmt; / 根據從 minsqlda 中獲取的長度,分配完整的 SQLDA 結構 fulsqlda,其中將包括合適數量的 SQLVAR 結構 fulsqlda = (struct sqlda *)malloc(SQLDASIZE(minsqlda-sqln); / 使用 DESCRIBE 語句,獲取結果集中每個字段的描述信息,包括各字段的類型 (sqltype) 和長度 (sqllen) EXEC SQL DESCRIBE STMT INTO :fulsqlda; Loop / 根據每個字段的長度,分配內存,將地址存儲在對應 SQLVAR 的 sqldata 中 / 聲明游標 EXEC SQL DECLARE c1 CURSOR FOR STMT; EXEC SQL OPEN c1; / 讀取記錄,記錄中每個字段的內容將寫入 fulsqlda 中對應 SQLVAR 結構的 sqldata 指向的內存 EXEC SQL FETCH c1 USING DESCRIPTOR :*fulsqlda; / 循環讀取所有記錄 while (sqlca.sqlcode != 100) EXEC SQL FETCH c1 USING DESCRIPTOR :*fulsqlda; EXEC SQL CLOSE c1;DB2 CLIDB2 CLI(Call Level Interface)基于微軟的 ODBC(Open Database Connectivity)標準,同時也增加了 DB2 特有的功能。它允許開發人員使用 C/C+ 語言訪問 DB2 并通過函數調用將動態 SQL 語句傳遞給 DB2。DB2 CLI 一方面在 ODBC 的環境中作為 ODBC 驅動被 ODBC 管理器加載,另一方面,應用程序也可以直接使用 DB2 CLI API,此時具有更好的性能。清單 6展示了 CLI 如何執行一個 DELETE 語句。 清單 6. CLI 應用程序片斷 /* SQL statements to be executed */ SQLCHAR * stmt1 = (SQLCHAR *)delete from test1 where col1 = 5; /* directly execute statement 1 */ cliRC = SQLExecDirect(hstmt, stmt1, SQL_NTS);對一個返回結果未知的 SELECT 查詢語句,需要使用相關的 CLI API 函數動態地獲取對結果集的描述,并取回數據。圖 2展示了這個處理過程。 圖 2. DB2 CLI 應用程序處理 SELECT 語句流程與嵌入式動態 SQL 應用相比,CLI 程序的靈活性更強。表 3列舉了 CLI 應用程序和嵌入式動態 SQL 應用程序的比較。 表 3. CLI 應用程序和嵌入式動態 SQL 應用程序的比較CLI嵌入式動態 SQLDB2 CLI 應用程序使用 API 函數發送 SQL 語句,應用程序的編譯、連接和運行獨立于特定數據庫,即無需預編譯,也不需要綁定到某個數據庫實例。嵌入式動態 SQL 應用程序需要預編譯,并且需要綁定到特定的數據庫實例。CLI 提供的滾動游標(scroll cursor)支持前、后向移動一行或者多行記錄,而移動的起點可以是第一行、最后一行或者之前存儲的位置。只支持順序前向讀取游標,并使用 FETCH 語句取得記錄。可以獲取存儲過程調用返回的結果集。并支持多種 DB2 服務器。可以獲取存儲過程的輸出型或輸入 - 輸出型參數的值,但不能獲取存儲過程返回的結果集。只支持 C/C+ 語言。支持 C/C+, FORTRAN、COBOL 和 Java(SQLJ)。使用 CLI API 函數 SQLDescribeCol()、SQLAttribute() 描述未知 SQL 語句結果集的信息,包括結果集字段長度、類型、精度等信息。使用 SQLDA 結構和 DESCRIBE 語句獲取未知 SQL 語句結果集的字段列表,包括類型、長度等信息。JDBCJDBC 是 Java 編程語言訪問關系型數據庫的工業標準,類似于 ODBC,為訪問基于 SQL 的數據庫提供了一組調用級的 API。在 JDBC 規范中,存在 4 種類型的 JDBC 驅動,DB2 LUW V9.7 中支持 Type 2 和 Type 4 兩種類型。更多關于 JDBC 的信息可參考 DB2 UDB for Linux, UNIX 和 Windows 中的 Java 開發概述(參見 參考資源部分)。 JDBC 以 Java 包的形式提供了一組接口和類,用來連接數據庫和執行 SQL 語句,這里的 SQL 語句也是動態 SQL,無須預編譯和數據庫綁定。清單 7所示為 JDBC 程序片斷。 清單 7. JDBC 應用程序片斷 try stmt = con.prepareCall(select * from table1); stmt.execute(); rs = stmt.getResultSet(); while (rs!=null && rs.next() System.out.println(output: = + rs.getInt(1); catch(SQLException sqle) System.out.println(Error, SQLCODE = + sqle.getSQLState(); con.rollback(); 除了編程語言和運行基礎架構的不同,JDBC 應用和 CLI 應用具有很多相似的特性,例如它們都支持后向游標,分布式事務等。 ADO.NET 和 OLE DBADO.NET 是 Microsoft .NET Framework 基礎類庫的一部分,提供了訪問關系型數據庫系統和其他數據源的能力。ADO.NET 主要包括兩個部分:DataSet 和 DataProvider。使用 ADO.NET,有三種 DataProvider 可以用來訪問 DB2: OLE DB .NET Data Provider 和 ODBC .NET Data Provider 是兩種橋接式 provider,它們將 ADO.NET 請求轉換為對 IBM OLE DB Provider 或 IBM ODBC Driver 的請求。 DB2 .NET Data Provider 是訪問 DB2 時推薦使用的 .NET provider,由于沒有額外的 OLE DB 或 ODBC 層,它具有更好的性能。 OLE DB 是一種較早出現的數據訪問模型,它基于 Microsoft 的 COM 技術,提供了訪問不同信息源的統一方法。OLE DB 定義了 OLE DB 消費者和提供者,OLE DB 消費者可以通過 IBM OLE DB Provider for DB2 訪問 DB2 中的數據。使用 OLE DB 訪問 DB2 的應用程序可能包括 Microsoft Visual Studio C+ 應用,Microsoft Visual Basic 應用,ATL 應用等。 其他應用程序開發接口Perl 程序員可以使用 Perl 數據庫接口 DBI 來訪問 DB2。IBM 提供的 DBI 驅動為 IBMDB2Database Driver for Perl DBI (the DBD:DB2 driver)。Perl DBI 同樣使用動態 SQL,而且 Perl DBI 的接口與 CLI 和 JDBC 很相似,易于使用。 PHP 在 Web 應用開發領域一直占據很大份額,IBM 提供了下面兩種 PHP 擴展以訪問 DB2 數據庫: ibm_db2,是一種過程化的應用編程接口,與 PHP 應用一起編譯,提供一系列的 PHP 函數來訪問數據庫。 pdo_ibm,是 IBM 提供的 PHP Data Objects (PDO) 驅動。 此外,IBM 對 Python,Ruby on Rails 等編程語言都提供了相應的 DB2 訪問支持。這些開發接口同樣都使用動態 SQL。 應用場景以及如何選擇本節將結合幾個應用場景來介紹如何選擇 DB2 編程接口以及靜態 / 動態 SQL。 場景 1銀行中賬目統計系統比較穩定,一般運行在一個特定的數據庫中,其目的是整合業務數據庫上數據,并通過分析數據得到一些相關的統計信息。這樣的系統具有以下一些特點 : 穩定,系統邏輯不會有什么變化,訪問固定的數據庫以及表。 定時運行,賬目統計信息通常需要在一段時間內進行整合。 數據量比較大,對性能要求較高。 針對這些特點,建議使用主要由靜態 SQL 語句組成的應用程序,這樣該系統在建立的時候會被編譯,然后相關的編譯信息會被存儲到數據庫里,在以后的運行過程中避免重復編譯,同時,這種應用由于結構 簡單使得其很容易維護。當然,由于系統的數據變化較快,而且數據量很大,所以建議定時重新編譯程序,使得數據庫對每條 SQL 語句可以選擇最優的運行方式。 場景 2考慮電信運營商對用戶話單的計費場景,圖 3顯 示了一個電信運行系統結構圖。業務系統產生的各種話單會集中存放在一個關系型數據庫中,該數據庫可能位于大規模的高可靠性服務器。而計費程序則往往作為一 個單獨的應用部署在其他規模較小的 UNIX 服務器上,并作為守護程序或者批處理程序運行。另外,很多業務規則例如計費標準可能存放在單獨得小型數據庫系統中。 圖 3. 電信運營系統結構示意圖計費程序的工作主要包括:從話單數據庫讀新話單,從業務配置數據庫讀取計費標準,計算話單的費用和優惠,將計費完畢的話單寫回話單數據庫。 由于計費標準的選擇經常和日期等變化的信息相關,程序中會存在一些不固定的 SQL 語句,因此靜態 SQL 應用并不適用。另外,除了訪問結構穩定的話單數據庫,計費程序也需要訪問一些變化概率較大的小型數據庫,例如計費標準可能會因為運營商營銷策略的調整而發 生變化。如果使用嵌入式 SQL,就必須將應用程序和數據庫進行綁定,這將
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 助貸電話銷售培訓課件
- 廚房安全知識培訓
- 2025天津市房屋租賃合同模板
- 2025年關于合同終止的程序與規定
- 2025授權收購協議合同范本格式
- 2025國際技術轉讓合同概念與主要條款研究
- 2025試用員工轉正合同模板
- 《中國戲曲·昆曲》(江蘇省昆劇院)章節測試答案
- 2025個人自建示范性房屋租賃合同模板
- 2025建筑外墻涂裝分項工程施工合同
- (完整)關于高壓線下施工安全專項方案
- 2022年新疆維吾爾自治區三校生高考語文備考試題及答案解析
- 國際學術交流英語知到章節答案智慧樹2023年哈爾濱工業大學
- 反三角函數正課
- 高考標準化考場建設的方案
- 乳腺癌NCCN指南中文版2022.v2
- GB/T 38942-2020壓力管道規范公用管道
- 家居建材全屋定制店面運營管理細則規定
- GB/T 27924-2011工業貨架規格尺寸與額定荷載
- 大班語言《他們看見了一只貓》課件
- 消毒產品進貨檢查驗收制度
評論
0/150
提交評論