память, выделенная драйвером jdbc для результата функции pl/sql

Согласно документу "Oracle JDBC Memory Management" драйвер Oracle jdbc выделяет буфер char[] при анализе оператора.

Размер буфера рассчитывается на основе максимально возможного размера данных строки, возвращаемых запросом.
Например, для оператора SELECT NAME FROM TAB, где NAME равно VARCHAR2(40), 40 *2 байта = будет выделено 80 байт.

Насколько большим будет буфер, если данные строки являются функцией с возвратом varchar2? Например:

select FOO from dual;

где ФОО

create or replace function FOO
return varchar2 is
...

person zxeka    schedule 02.03.2012    source источник
comment
Я не уверен, но если документ говорит, что jdbc выделит максимально возможный результат, в этом случае будет 32767 (максимум в PL/SQL).   -  person    schedule 02.03.2012


Ответы (2)


я создал функцию

CREATE FUNCTION TEMP_ADAM_FUNC RETURN VARCHAR2 IS
BEGIN
  RETURN 'TEST';
END;

И я запросил его следующим образом:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT TEMP_ADAM_FUNC FROM DUAL");
results.next();
results.getString(1);

Пропустив это через отладчик, вы увидите, что драйвер выделил значительный объем памяти:

введите здесь описание изображения

Фактически драйвер выделил 65535 символов для столбца VARCHAR2.

Я выполнил другой запрос:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT DUMMY FROM DUAL");
results.next();
results.getString(1);

Я подтвердил размер столбца DUMMY, используя этот запрос:

SELECT
  DATA_TYPE,
  DATA_LENGTH
FROM
  ALL_TAB_COLUMNS
WHERE
  TABLE_NAME = 'DUAL' AND COLUMN_NAME = 'DUMMY'

Этот запрос дал 'VARCHAR2' и 1 соответственно.

Однако в данном случае драйвер выделил 4096 символов:

введите здесь описание изображения

Я не очень уверен, что управляет этой логикой.

person Adam Paynter    schedule 02.03.2012

Немного не по касательной от вашего вопроса...

Как упоминалось на странице 5 официального документа, на который вы ссылались, если вы можете использовать OracleStatement, вы можете использовать defineColumnType, чтобы ограничить размер и, следовательно, объем памяти, зарезервированной для столбца.

Таким образом, вы можете указать меньший размер, чем размер по умолчанию, когда размер не фиксирован, как в вашем вызове функции, или если вы возвращаете курсор ref; что может сэкономить значительный объем памяти (поскольку вы можете получить 32 КБ — или даже больше, основываясь на исследовании Адама — умноженное на количество строк, которые вы предварительно выбираете). Вы также можете указать размер для столбцов, размер которых вам известен, что может избавить вас от необходимости обращаться к базе данных для тех, которые нужно искать при подготовке оператора. В любом случае, если вы зададите слишком маленькое число и получите столбец с более длинным значением, чем разрешено, вы получите сообщение об ошибке.

person Alex Poole    schedule 02.03.2012