Получение ResultSet/RefCursor через ссылку на базу данных
Из ответов на вызов хранимого процесса через dblink кажется, что невозможно вызвать хранимую процедуру и получить ResultSet/RefCursor обратно, если вы делаете вызов SP через удаленную ссылку на DB. Мы также используем Oracle 10g.
Мы можем успешно получить результаты с одним значением по ссылке, и можем успешно вызвать SP и получить результаты локально, но мы получаем ту же ошибку "ORA-24338: дескриптор оператора не выполнен" при чтении ResultSet из удаленной БД.
Мой вопрос - есть ли обходной путь к использованию хранимой процедуры? Является ли общий вид лучшим решением? Трубопроводные ряды?
Пример хранимой процедуры:
CREATE OR REPLACE PACKAGE BODY example_SP
IS
PROCEDURE get_terminals(p_CD_community IN community.CD_community%TYPE,
p_cursor OUT SYS_REFCURSOR)
IS
BEGIN
OPEN p_cursor FOR
SELECT cd_terminal
FROM terminal t, community c
WHERE c.cd_community = p_CD_community
AND t.id_community = c.id_community;
END;
END example_SP;
/
Пример кода Java, который работает локально, но не удаленно:
Connection conn = DBConnectionManagerFactory.getDBConnectionManager().getConnection();
CallableStatement cstmt = null;
ResultSet rs = null;
String community = "EXAMPLE";
try
{
cstmt = conn.prepareCall("{call example_SP.get_terminals@remote_address(?,?)}");
cstmt.setString(1, community);
cstmt.registerOutParameter(2, OracleTypes.CURSOR);
cstmt.execute();
rs = (ResultSet)cstmt.getObject(2);
while (rs.next())
{
LogUtil.getLog().logInfo("Terminal code=" + rs.getString( "cd_terminal" ));
}
}
1 ответ
Вариант 1. Перейти к прямому подключению из Java к удаленной базе данных, а не через локальную базу данных. Проще, но это зависит от приложения, чтобы координировать две отдельные транзакции. Если бы одна база данных использовалась только для чтения, а не для записи, я бы пошел по этому пути.
Вы можете использовать прямой запрос или хранимую процедуру и курсор ref. Как правило, я бы пошел с первым, если нет веских причин для добавления в слой хранимых процедур.
Вариант 2. Перейти на прямой запрос в локальной базе данных, используя ссылку на базу данных.
Вариант 3. Как (2), но скрыть запрос в представлении (или синониме), хранящемся в локальной базе данных.
Вариант 4. Если результирующий набор достаточно мал, у вас может быть процедура в локальной базе данных, вызывающая процедуру в удаленной базе данных. Удаленная процедура возвращает результат в виде XML или структурированного CLOB (например, JSON), который может быть "декодирован" либо локальной процедурой, либо уровнем java.