2014-10-09 66 views
0

我使用的是h2 v1.3.176。
我有執行RECURSIVE查詢的用戶定義函數。H2多次調用用戶定義函數

public static ResultSet getChildCategories(Connection connection, long categoryId) throws SQLException { 
    String sql = 
      "WITH RECURSIVE r(CATEGORY_ID, PARENT_ID) AS (\n" + 
      " SELECT CATEGORY_ID\n" + 
      "   ,PARENT_ID\n" + 
      " FROM  CATEGORY\n" + 
      " WHERE CATEGORY_ID = " + categoryId + "\n" + 
      " UNION ALL\n" + 
      " SELECT CATEGORY.CATEGORY_ID\n" + 
      "   ,CATEGORY.PARENT_ID\n" + 
      " FROM  CATEGORY, r\n" + 
      " WHERE CATEGORY.PARENT_ID = r.CATEGORY_ID\n" + 
      ")\n" + 
      "SELECT CATEGORY_ID FROM r"; 
    ResultSet resultSet = connection.createStatement().executeQuery(sql); 
    SimpleResultSet rs = new SimpleResultSet(); 
    rs.addColumn("CATEGORY_ID", Types.INTEGER, 12, 0); 
    try { 
     while(resultSet.next()) { 
      rs.addRow(resultSet.getLong(1)); 
     } 
    } finally { 
     resultSet.close(); 
    } 
    return rs; 
} 

我已經通過以下SQL註冊了此函數。

create alias GET_CHILD_CATEGORIES for "com.myapp.db.function.Functions.getChildCategories"; 

我的問題是,當我執行以下查詢getChildCategories函數將被調用多次。

SELECT DISTINCT B.BOOK_ID 
       ,B.SERIES_ID 
       ,B.TITLE 
       ,B.ISBN 
       ,B.VOLUME 
       ,(
        SELECT MAX(SAME_SERIES.VOLUME) 
        FROM BOOK SAME_SERIES 
        WHERE SAME_SERIES.SERIES_ID = B.SERIES_ID 
        AND  SAME_SERIES.VOLUME IS NOT NULL 
       ) AS VOLUME_COUNT 
       ,B.PAGE_COUNT 
       ,B.FILE_PATH 
       ,B.SORTABLE_FILE_NAME 
       ,B.SIZE 
       ,B.HASH 
       ,B.COVER_IMAGE_TYPE 
       ,B.COVER_PAGE_NO 
       ,B.COVER_LARGE_IMAGE_URL 
       ,B.COVER_SMALL_IMAGE_URL 
       ,B.COVER_CROP_COORD 
       ,B.IS_ENCRYPT 
       ,B.PUBLISHER_ID 
       ,B.PUBLISHED_DATE 
       ,B.CREATION_TIME 
       ,B.LAST_MODIFIED_TIME 
       ,B.NOTE 
       ,B.IS_ISBN_SEARCH 
       ,S.CATEGORY_ID 
       ,S.TITLE 
       ,BA.AUTHOR_ID 
       ,BT.TAG_ID 
FROM    BOOK AS B 
INNER JOIN  SERIES AS S ON S.SERIES_ID = B.SERIES_ID 
LEFT OUTER JOIN BOOK_TAG AS BT ON BT.BOOK_ID = B.BOOK_ID 
LEFT OUTER JOIN BOOK_AUTHOR AS BA ON BA.BOOK_ID = B.BOOK_ID 
WHERE 
(
    S.CATEGORY_ID IN (SELECT CATEGORY_ID FROM GET_CHILD_CATEGORIES(106)) 
    And 
    S.IS_COMPLETION = 1 
) 
ORDER BY BA.AUTHOR_ID 

爲什麼很多時候會調用該函數?

回答

0

H2 documentation

提取的返回結果集可以像表中使用的函數。 但是,在這種情況下,函數至少調用兩次:第一個爲 ,同時解析語句以收集列名( 參數設置爲null,在編譯時未知的地方)。然後, 執行語句來獲取數據(如果 這是一個連接可能多次)。如果僅爲獲取列 列表而調用該函數,則傳遞給該函數的連接的URL爲 jdbc:columnlist:connection。否則,連接的URL是 jdbc:default:connection。

第一次調用僅用於檢索結果集列類型。然後你必須檢查連接url是否爲「jdbc:columnlist:connection」。如果爲true,則必須返回列列表爲空的結果集。

連接URL測試:

connection.getMetaData().getURL().equals("jdbc:columnlist:connection"); 
+0

太感謝你了!就像你說的那樣。 我能夠改善查詢性能。 – user1428896 2014-10-10 14:36:12