Я пытаюсь создать функцию JRT, которая принимает параметр типа INTERVAL
. Мой запрос может предоставить любой тип INTERVAL
, но я бы предпочел использовать тип INTERVAL DAY
, если это возможно.
Согласно документации H SQL , моя функция должна выглядеть примерно так как:
public static String exampleHsqlFunction(final java.time.Period duration) {
return "In example function, arg: " + duration.toString();
}
Затем функция должна быть зарегистрирована. В документации не указан тип INTERVAL DAY
, указанный в документации, поэтому вместо него я буду использовать INTERVAL MONTH
:
CREATE FUNCTION EXAMPLE_FUNCTION (duration INTERVAL MONTH)
RETURNS CHAR VARYING(100)
LANGUAGE JAVA DETERMINISTIC NO SQL
EXTERNAL NAME 'CLASSPATH:hsqltest.HsqlIntervalFunctionTest.exampleHsqlFunction';
Пока все хорошо, моя функция зарегистрирована правильно и ошибки не отображаются.
Теперь я создам фиктивную таблицу, чтобы у меня было что-то для SELECT
при тестировании функции:
CREATE TABLE DUMMY(id INT); INSERT INTO DUMMY VALUES (0);
Наконец, я могу попробовать вызвать саму функцию:
SELECT EXAMPLE_FUNCTION(INTERVAL '3' MONTH) FROM DUMMY;
aa и я получаю сообщение об ошибке:
java .lang.IllegalArgumentException: несоответствие типов аргументов
Я сделал некоторую отладку, установил точку останова в java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
и получается, что H SQL передает org.hsqldb.types.IntervalMonthData
в качестве аргумента методу (или org.hsqldb.types.IntervalSecondData
для INTERVAL SECOND
типа).
Когда тип параметра метода Java изменяется на IntervalMonthData
, однако H SQL не может его распознать:
org.hsqldb.HsqlException: Java выполнение: неразрешенное имя класса, имя метода или подпись
Я также попробовал некоторые глупости, такие как передача INTERVAL '3' DAY
в качестве аргумента. Затем выдается следующее исключение:
org.hsqldb.HsqlException: исключение данных: интервал переполнения поля
Функция работает, если мы изменим параметр на какой-то другой тип, например INT
и соответствующий Integer
. Это всего лишь INTERVAL
, что кажется ненадежным.
Я использую H SQL в версии 2.5.0
(новейшей в Maven Central), минимальный рабочий пример:
package hsqltest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public final class HsqlIntervalFunctionTest {
public static String exampleHsqlFunction(final java.time.Period duration) {
return "In example function, arg: " + duration.toString();
}
public static void main(final String... args) throws SQLException {
try (
final Connection connection = DriverManager.getConnection(
"jdbc:hsqldb:mem:testdb",
"sa",
"sa"
);
final Statement statement = connection.createStatement()
) {
// create function and link it to Java method
statement.executeUpdate(
"CREATE FUNCTION EXAMPLE_FUNCTION (duration INTERVAL MONTH)"
+ " RETURNS CHAR VARYING(100)"
+ " LANGUAGE JAVA DETERMINISTIC NO SQL"
+ " EXTERNAL NAME 'CLASSPATH:hsqltest.HsqlIntervalFunctionTest.exampleHsqlFunction';"
);
// create dummy table so we have something to SELECT from
statement.executeUpdate("CREATE TABLE DUMMY(id INT);");
statement.executeUpdate("INSERT INTO DUMMY VALUES (0);");
// use the function and print the result
final ResultSet result = statement.executeQuery(
"SELECT EXAMPLE_FUNCTION(INTERVAL '3' MONTH) FROM DUMMY;"
);
while (result.next()) {
System.out.println(result.getString(1));
}
}
}
}