Отправляет email-рассылки с помощью сервиса Sendsay

Килограмм килобайтов

  Все выпуски  

Килограмм килобайтов


"Килограмм килобайтов"


Выпуск №42 Дата выхода:2008-11-25
Сайт рассылки: Рациональное программирование

Документация
 
Программирование
Java
PHP
Oracle
Операционные системы
FreeBSD
Linux
QNX
Windows

Здравствуйте, уважаемые подписчики

Рассылка выходит из отпуска и продолжает свою работу.
Планируемая периодичность выпусков - раз в две недели.

От одного из подписчиков я получил такой вопрос.

Как поставить виртуальный компьютер[ например Java Virtual Machine] в резидентный режим? Это такой режим когда программа находиться в постоянно загруженном состоянии.
Заранее спасибо.

Может быть кто-нибудь знает, как ответить?

Я подготовил материал об использовании выражения BULK COLLECT в Oracle.
Статья делится на три часть. Первая часть в этом выпуске, следующие две выйдут в автоматическом режиме в следующих двух выпусках с интервалом в две недели.
Для нетерпеливых спешу сообщить, что полностью статья будет опубликована на сайте рассылки в течение нескольких дней.
Итак, первая часть статьи.

Использование выражения BULK COLLECT

Предлагаю вам мой перевод части документации Oracle® Database PL/SQL User's Guide and Reference 10g Release 2 (10.2) B14261-01

v:1.0 2008.11.24

Если для Вас выборка большого количества данных и помещение их в переменную PL/SQL важнее чем циклический проход по результирующей выборке, то Вы можете использовать выражение BULK COLLECT. Если в Вашей выборке всего несколько колонок, то каждую из них Вы можете сохранить в отдельную переменную - коллекцию. Если Вы выбираете все колонки таблицы, то можете сохранить результат выборки в коллекции записей. Такая коллекция весьма удобна для циклического перебора результирующих записей, поля которых ссылаются на колонки таблицы.

Пример


DECLARE
  TYPE    IdsTab IS TABLE OF employees.employee_id%TYPE;
  TYPE    NameTab IS TABLE OF employees.last_name%TYPE;
  ids      IdsTab;
  names NameTab;
  CURSOR c1 IS
  SELECT employee_id, last_name 
       FROM employees 
    WHERE job_id = 'ST_CLERK';
BEGIN
  OPEN c1;
  FETCH c1 BULK COLLECT INTO ids, names;
  CLOsE c1;
-- Обработка элементов коллекции
 FOR i IN ids.FIRST..ids.LAST
 LOOP
   IF ids(i) > 140 THEN
     DBMS_OUTPUT.PUT_LINE(ids(i));
   END IF;
 END LOOP;
 FOR i IN names.FIRST..names.LAST
 LOOP
   IF names(i) LIKE '%Ma%' THEN
     DBMS_OUTPUT.PUT_LINE(names(i));
   END IF;
 END LOOP;
END;
/

Эта технология может быть не только очень быстрой, то и требовательной к памяти.

    Используя BULK COLLECT, Вы можете улучшить код, выполняя больше работы в SQL:
  • Если Вам надо пройти по результирующей выборке только один раз, используйте цикл For. Этот подход позволяет избежать выделение памяти на хранение копии результирующих данных.
  • Если из результирующих данных Вам требуется выбрать определенные значения и поместить их в меньшую выборку, используйте фильтрацию в основном выражении. В простом случае используйте условия WHERE. Для сравнения двух и более наборов данных применяйте выражения INTERSECT и MINUS.
  • Если Вы циклически проходите по результирующей выборке и для каждого ряда выполняете DML-выражение или делаете другую выборку, используйте более эффективных подход. Попробуйте вложенную выборку переделать в подзапрос основной выборки, если возможно, используйте выражения EXISTS или NOT EXISTS. Для DML, рассмотрите возможность использования выражения FORALL, который значительно более быстрый, чем аналогичное выражение, выполненное внутри цикла.

Еще один пример использования BULK COLLECT



DECLARE
  TYPE EmployeeSet IS TABLE OF employees%ROWTYPE;
  underpaid EmployeeSet; -- Набор рядов таблицы EMPLOYEES.

  CURSOR c1 IS SELECT first_name, last_name FROM employees;
  TYPE NameSet IS TABLE OF c1%ROWTYPE;
   some_names NameSet; -- Набор неполных рядов таблицы EMPLOYEES

BEGIN

-- С помощью одного запроса мы извлекаем все данные, соответствующие условиям, в коллекцию записей

SELECT * BULK COLLECT 
    INTO underpaid 
    FROM employees
  WHERE salary < 5000 
 ORDER BY salary DESC;

-- Сейчас мы можем обработать данные, выбранные запросом, или передать их в отдельную процедуру.

  DBMS_OUTPUT.PUT_LINE(underpaid.COUNT || ' people make less than 5000.');
  FOR i IN underpaid.FIRST..underpaid.LAST
  LOOP
    DBMS_OUTPUT.PUT_LINE(underpaid(i).last_name || ' makes ' ||  underpaid(i).salary);
  END LOOP;

-- А сейчас мы сделаем выборку только по некоторым полям таблицы.
-- Получим фамилию и имя десяти случайных сотрудников.

  SELECT first_name, last_name BULK COLLECT 
        INTO some_names 
       FROM employees
     WHERE ROWNUM < 11;

 FOR i IN some_names.FIRST..some_names.LAST
 LOOP
   DBMS_OUTPUT.PUT_LINE('Employee = ' || some_names(i).first_name || ' ' ||
   some_names(i).last_name);
 END LOOP;
END;
/

Продолжение следует...


* * *

Ведущий рассылки: Петрелевич Сергей

У Вас есть вопрос? Спрашивайте
Напишите, что Вы хотите видеть в рассылке. Мне важно знать Ваше мнение.


В избранное