程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 在 DB2 V9 for z/OS 中通過類型 2 連接支持多行獲取

在 DB2 V9 for z/OS 中通過類型 2 連接支持多行獲取

編輯:DB2教程

簡介

IBM DB2 Driver for JDBC and SQLJ 有一個稱為 useRowsetCursor 的數據源屬性。該屬性的默認值是 true,這意味著在服務器支持的情況下,驅動程序將嘗試對可滾動游標使用多行獲取(MRF)。該屬性允許應用程序在必要時將 MRF 設置為 off。還沒有針對單進游標的 MRF 支持。另外,T2zos (DB2 V9 for z/OS) 尚未支持 MRF。

目前,MRF 支持有 3 個公共接口:

public void setUseRowsetCursor (boolean useRowsetCursor);

public boolean getUseRowsetCursor ();

public boolean getUseRowsetCursor (Java.util.Properties propertIEs);

不過,這不能當成 T2zos 的常規解決方案。這是因為 T2zos 需要行集支持來獲得默認的 false 或 unset。該需求導致需要使用新的屬性覆蓋當前的 useRowsetCursor 屬性(將在下面的 新連接屬性 小節進一步闡述該屬性)。另外,對於 T2zos,新的屬性可用於單進游標和可滾動游標。在 IBM DB2 Driver for JDBC and SQLJ 版本 3.7.xx、3.51.xx、4.1.xx 和更新版本中,都啟用了 MRF for T2zos (DB2 V9 for z/OS) 額外支持。

什麼是多行獲取?

多行獲取允許您從結果表中獲取 0 行或多行。與獲取一個行不同,您可以獲取一組行(稱為行集)。

如 圖 1 所示,通過獲取多個行,應用程序減少了 SQL 調用,並且可以使用一個 FETCH 語句獲取行集。這不僅減少 SQL Application Programming Interface (API) 的交叉使用,還減少了應用程序的該函數的 CPU 使用。

圖 1. 單行獲取和多行獲取比較
在 DB2 V9 for z/OS 中通過類型 2 連接支持多行獲取 

新連接屬性

與 MRF 相關的新連接屬性是 enableRowsetSupport。該屬性的可用值包括:

NOT_SET(默認值)

YES

NO

當 enableRowsetSupport 連接屬性設置為 YES 或 NO 時,它將使用 useRowsetCursor 覆蓋當前的設置。

對於 T2zos,如果 enableRowsetSupport 的值為 NOT_SET,這意味著沒有 MRF 支持。對於 T4 和 T2u,NOT_SET 導致使用 useRowsetCursor 屬性的當前值,該屬性的默認值為 true。這意味著如果服務器在 T4 和 T2u 上支持它,將僅對可滾動游標使用 MRF。T4 和 T2u 用戶可以將 useRowsetCursor 設置為 false 或將 enableRowsetSupport 設置為 NO 關閉該行為。

要啟用 MRF,將 enableRowsetSupport 設置為 YES。如果服務器支持,T2zos 將對可滾動游標和單進游標使用 MRF。在未來,T4 和 T2u 可能選擇僅對單進游標使用 MRF。

要禁用 MRF,將 enableRowsetSupport 設置為 NO。這意味著 MRF 對所有類型的用戶禁用(T2zos、T4 和 T2u)。

下面是用於覆蓋 useRowsetCursor 屬性的當前設置的新屬性:

public void setEnableRowsetSupport(int enableRowsetSupport);

public int getEnableRowsetSupport();

public int getEnableRowsetSupport(Java.util.Properties propertIEs);

樣例 Java 程序

清單 1 使用一個樣例 Java 程序,它演示如何使用新的 enableRowsetSupport 連接屬性覆蓋當前的 useRowsetCursor 屬性。

該程序將 enableRowsetSupport 設置為 YES,這意味著將啟用 MRF。

import Java.sql.*; 
 
public class connectionInfo_MRF 
{ 
 public static void main(String[] args) throws Exception 
 { 
  System.out.println("\nTest case begins !!!\n "); 
      
  Javax.sql.DataSource ds = new com.ibm.db2.jcc.DB2SimpleDataSource(); 
      
  ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setServerName("ServerName"); 
  ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setPortNumber(portNumber); 
  ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setDatabaseName("databaseName"); 
  ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setDriverType(2); 
      
  // Enable MRF support. To disable MRF, set setEnableRowsetSupport 
  // to com.ibm.db2.jcc.DB2BaseDataSource.YES 
  
  int setValue = com.ibm.db2.jcc.DB2BaseDataSource.YES; 
  ((com.ibm.db2.jcc.DB2BaseDataSource)ds).setEnableRowsetSupport(setValue); 
  
  ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setTraceFile("jccTrace.txt"); 
  
  System.out.println(((com.ibm.db2.jcc.DB2BaseDataSource) ds).getJccVersion()); 
  
  Java.sql.Connection con = ds.getConnection("userName", "passWord"); 
  
  // Get Rowset support value. When MRF is enabled this should return value 1. 
  int RowSet = ((com.ibm.db2.jcc.DB2BaseDataSource)ds).getEnableRowsetSupport(); 
  
  System.out.println("\nRow Set Support value :" +RowSet); 
  System.out.println("\n"); 
  
  // Set the cursor type to scrollable. 
  //Modify the below statement if you want the cursor type to be TYPE_FORWARD_ONLY 
  Java.sql.Statement s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
                        ResultSet.CONCUR_READ_ONLY); 
  // Create table 
  s.executeUpdate ("create table TestQBatch (col1 int)"); 
  
  // Populate tables with data. 
  for (int i =1; i less than 1000; i++) 
  { 
  s.executeUpdate ("insert into TestQBatch values (" +i+ ")"); 
  } 
  
  Java.sql.ResultSet rs = s.executeQuery("Select * from TestQBatch"); 
  
  while (rs.next()) 
  { 
   System.out.print (rs.getInt (1) + " "); 
  } 
  
  // When MRF is enabled, ResultSet.getFetchSize() should alway return value > 1. 
  int ActualResult = rs.getFetchSize(); 
  
  System.out.print ("\n\nFetch Size : " +ActualResult); 
  
  // Drop the table created. 
 s.executeUpdate("DROP TABLE TestQBatch"); 
  
  System.out.println("\n\nTest case Ends !!! "); 
  
  con.commit(); 
  
 } 
} 

如何確定是否對獲取使用 MRF

在包含 IBM DB2 Driver for JDBC and SQLJ 版本 3.7.xx、3.51.xx、4.1.xx 或更新版本的 T2zos (DB2 V9 for z/OS) 機器上運行 清單 1 中的樣例程序。找到名為 jccTrace.txt 的 JCC 跟蹤文件。如前所述,在支持 MRF 的 T2zos 服務器上,如果 enableRowsetSupport 設置為 YES,T2zos 為游標准備 WITH ROWSET POSITIONING。

如果 jccTrace.txt 跟蹤文件包含字符串 WITH ROWSET POSITIONING,這意味著啟用了 MRF。如果沒有啟用 MRF,准備 FETCH 語句時將不包含行集定位。所以在這個例子中,您不能在跟蹤文件中找到字符串 WITH ROWSET POSITIONING。

您還可以通過調用 ResultSet.getFetchSize() 確定特定 ResultSet 的 MRF 是否處於活動狀態。如果 fetchSize 的返回值大於 1,那麼就使用了 MRF。注意,這是 ResultSet 而不是 PreparedStatement 上的調用。

限制

由於受到 DB2 的限制,行集游標(MRF)與 T2zos (Fetch Continue) 中的漸進式流不兼容。

在 T2zos 中,如果您將 enableRowsetSupport 設置為 YES,並且服務器支持 MRF,那麼 T2zos 將為游標准備 WITH ROWSET POSITIONING。不過,如果在游標中出現大對象或 XML,並且漸進式流使用默認值或設置為 on,將對 FETCH 語句關閉 MRF(OFF )。將重新准備 FETCH 語句,並且不包含行集定位。

T2zos 不知道從存儲過程返回的游標是不是一個行集,因此 t2zos 驅動程序僅允許對存儲過程執行單行獲取。

T2zos 不支持從存儲過程返回的並且是漸進式流形式的大對象或 XML。在獲取繼續 (T2zosCursor.getMoreData_) 調用期間,該情況可能導致拋出 -225 sqlcode。

如果游標中出現大對象或 XML,T2zos Java 存儲過程將關閉行集支持。

結束語

使用多行獲取 (MRF),您可以獲得比使用 FETCH 語句每次獲取一行更佳的性能。本文幫助您理解了 MRF 及其使用方式。此外,還通過一個簡單的樣例 Java 程序演示如何在 Java 程序中設置 MRF,並解釋如何確定是否使用了 MRF。

多行定位 UPDATE 或 DELETE

IBM Data Server Driver for JDBC and SQLJ 支持執行遵循 JDBC 1 標准的定位 UPDATE 或 DELETE 操作。對於行集游標,JDBC 1 定位更新語法必須知道行集的存在。該語法必須遵循以下格式:

update table set.... where current of cursor for row N of rowset

如果應用程序想要使用 JDBC 1 定位 UPDATE 操作,那麼它必須構建正確定位的 UPDATE/DELETE 語句。

不過,當前的 t2zos 應用程序仍然使用 JDBC 1 定位 UPDATE 語句,其遵循的格式如下:

update table set....where current of cursor

因此,行集支持導致不同的行為。UPDATE 影響整個行集,而不是單個行。因此,t2zos 行集支持的默認設置為 false(見 新連接屬性 小節)。

該技術涉及到使用 ResultSet.getCursorName 方法為 ResultSet 獲取游標的名稱,以及按照以下格式定義定位 UPDATE 或定位 DELETE 語句:

UPDATE table SET col1=value1…coln=valueN WHERE CURRENT OF cursorname

DELETE FROM table WHERE CURRENT OF cursorname

如果您使用 JDBC 1 技術對支持多行獲取的數據源中的數據執行 UPDATE 或 DELETE 操作,定位 UPDATE 或 DELETE 語句可能 UPDATE 或 DELETE 多個行,盡管您可能希望它僅 UPDATE 或 DELETE 單個行。

要避免意外的 UPDATE 或 DELETE 操作,您可以采取以下措施之一:

使用可更新的 ResultSet 一次僅獲取和 UPDATE 一個行。

在 UPDATE 或 DELETE 語句中使用 FOR ROW n OF ROWSET 子句, 以識別需要執行 MODIFY 或 DELETE 操作的特定行。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved