首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 V9 for z/OS 類型 2 連接的多行獲取 (MRF) 支援指南

     編輯:DB2 教學

簡介

IBM DB2 Driver for JDBC and SQLJ 提供了一個名為 useRowsetCursor 的數據源屬性,其預設值為 true。這意味著在伺服器支援的情況下,驅動程式會嘗試對可捲動游標使用多行獲取(MRF)。該屬性允許應用程式在必要時關閉 MRF。目前尚無針對前向游標的 MRF 支援,且 T2zos (DB2 V9 for z/OS) 早期版本不支援 MRF。

現有公共介面

目前 MRF 支援有三個公共介面:

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. 單行獲取和多行獲取比較

新連接屬性:enableRowsetSupport

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

  • NOT_SET(預設值)
  • YES
  • NO

當 enableRowsetSupport 設為 YES 或 NO 時,它會覆蓋 useRowsetCursor 的當前設定。

  • T2zos:若值為 NOT_SET,表示無 MRF 支援。
  • T4 和 T2u:NOT_SET 會使用 useRowsetCursor 的當前值(預設為 true),即僅在伺服器支援時對可捲動游標使用 MRF。用戶可將 useRowsetCursor 設為 false 或 enableRowsetSupport 設為 NO 來關閉該行為。

若要啟用 MRF,將 enableRowsetSupport 設為 YES。若伺服器支援,T2zos 將對可捲動游標和前向游標均使用 MRF。未來 T4 和 T2u 可能選擇僅對前向游標使用 MRF。若要禁用 MRF,將 enableRowsetSupport 設為 NO,這將對所有類型的用戶(T2zos、T4、T2u)禁用 MRF。

新屬性的公共介面

public void setEnableRowsetSupport(int enableRowsetSupport);
public int getEnableRowsetSupport();
public int getEnableRowsetSupport(java.util.Properties properties);

範例 Java 程式

清單 1 示範如何使用新的 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.NO
        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 < 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 always 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 語句時將不包含行集定位,因此追蹤檔中找不到該字串。

您也可透過呼叫 ResultSet.getFetchSize() 確定特定 ResultSet 的 MRF 是否活躍。若 fetchSize 回傳值大於 1,則表示使用了 MRF。注意,這是在 ResultSet 而非 PreparedStatement 上呼叫。

限制

  • 由於 DB2 限制,行集游標(MRF)與 T2zos (Fetch Continue) 中的漸進式流不相容。
  • 在 T2zos 中,若啟用 enableRowsetSupport=YES 且伺服器支援 MRF,T2zos 會為游標準備 WITH ROWSET POSITIONING。但若游標中出現大型物件 (LOB) 或 XML,且漸進式流使用預設值或設為 on,則會對 FETCH 語句關閉 MRF(OFF),並重新準備不含行集定位的 FETCH 語句。
  • T2zos 無法得知從預存程序返回的游標是否為行集,因此驅動程式僅允許對預存程序執行單行獲取。
  • T2zos 不支援從預存程序返回且為漸進式流形式的 LOB 或 XML。在獲取繼續 (T2zosCursor.getMoreData_) 呼叫期間,可能拋出 -225 sqlcode。
  • 若游標中出現 LOB 或 XML,T2zos Java 預存程序將關閉行集支援。

結束語

使用多行獲取 (MRF),您可以獲得比使用 FETCH 語句每次獲取一行更佳的性能。本文幫助您理解 MRF 及其使用方式,並透過範例 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 應用程式仍使用舊格式:

update table set....where current of cursor

因此,行集支援導致不同行為:UPDATE 會影響整個行集而非單行。故 t2zos 行集支援預設為 false(見「新連接屬性」一節)。

該技術涉及使用 ResultSet.getCursorName 取得游標名稱,並按以下格式定義定位 UPDATE 或 DELETE:

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

若在支援多行獲取的資料源上使用 JDBC 1 技術執行 UPDATE 或 DELETE,定位語句可能更新或刪除多行,即使您僅想操作單行。

為避免非預期操作,可採取以下措施:

  • 使用可更新的 ResultSet 一次僅獲取並 UPDATE 一行。
  • 在 UPDATE 或 DELETE 語句中使用 FOR ROW n OF ROWSET 子句,以識別需修改或刪除的特定行。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved