我正在使用h2 v1.3.176 我有用户定义的函数来执行RECURSIVE查询。
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 :(得分:0)
返回结果集的函数可以像表一样使用。 但是,在这种情况下,函数至少被调用两次:首先 在解析语句以收集列名时(使用 参数设置为null,在编译时未知。然后, 在执行语句以获取数据时(可能多次执行) 这是一个加入)。如果调用该函数只是为了获取列 list,传递给函数的连接的URL是 JDBC:columnlist:连接。否则,连接的URL是 JDBC:默认:连接
第一次调用仅用于检索结果集列类型。然后你必须检查连接URL是否是" jdbc:columnlist:connection"。如果为true,则必须返回带有列列表的空结果集。
连接网址测试是:
connection.getMetaData().getURL().equals("jdbc:columnlist:connection");