Вход/Регистрация
Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
вернуться

Борри Хелен

Шрифт:

. . .

DECLARE VARIABLE DBK CHAR (8);

/* 8 символов для db_key таблицы А */

. . .

FOR SELECT B.FK,

SUM(B.VALUEFIELD) ,

A. RDB$DB_KEY

FROM TABLEB В

JOIN TABLEA A ON A.PK = B.FK

WHERE <условия>

GROUP BY B.FK, A.RDB$DB_KEY

INTO :B_FK, :TOTAL, :DBK DO

UPDATE TABLEA SET A.TOTAL = :TOTAL

WHERE A.RDB$DB_KEY = :DBK;

! ! !

ПРИМЕЧАНИЕ. В Firebird нет необходимости в ключевом столбце для создания соединения, однако он нужен в списке SELECT, чтобы предложение GROUP BY было допустимым.

. ! .

Перечислим преимущества такого подхода.

* Фильтрация общих записей для А и В будет эффективной, когда оптимизатор может создать хороший фильтр для явного соединения.

* Если соединение может применить свое собственное предложение поиска, то существует выгода от выполнения фильтрации до того, как изменение будет проверять свое собственное условие.

* Строки таблицы правой стороны (А), локализованные с помощью прямых указателей db key, выделяются во время соединения быстрее, чем при просмотре первичного ключа или его индекса.

Добавления

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

Однако не все входные значения(VALUE2) оператора INSERT получаются так просто.

Это может быть очень сложным набором значений, полученным из выражений, со-

единений или агрегатных операций. В хранимой процедуре операция INSERT может разветвляться в предложении ELSE предиката IF (EXISTS (...)), например:

IF EXISTS(SELECT...) THEN

. . .

ELSE

BEGIN

INSERT INTO TABLEA

SELECT

C.PKEY,

SUM (B. AVALUE) ,

AVG(B.BVALUE),

COUNT(DISTINCT C.XYZ)

FROM TABLEB B JOIN TABLEC С

ON B.X = C.Y

WHERE C.Z = 'value'

AND С.PKEY NOT IN(SELECT PKEY FROM TABLEA)

GROUP BY С.PKEY;

END

. . .

Реализация этого в хранимой процедуре:

FOR SELECT

С.PKEY,

SUM(B.AVALUE),

AVG(B.BVALUE),

COUNT(DISTINCT C.XYZ)

FROM TABLEB B JOIN TABLEC С

ON B.X = C.Y

WHERE C.Z = 'value'

AND С.PKEY NOT IN(SELECT PKEY FROM TABLEA)

GROUP BY С.PKEY

INTO :C_KEY, :TOTAL, :B_AVG, :C_COUNT DO

BEGIN

SELECT A.RDB$DBKEY FROM TABLEA A

WHERE A.PKEY = :C_KEY

INTO :DBK;

IF (DBK IS NULL) THEN /* строка не существует */

INSERT INTO TABLEA(PKEY, TOTAL, AVERAGE_B, COUNT_C)

VALUES(:C_KEY, :TOTAL, :B_AVG, :C_COUNT);

ELSE

UPDATE TABLEA SET

TOTAL = TOTAL + :TOTAL,

AVERAGE_B = AVERAGE_B + :B_AVG,

COUNT_C = COUNT_C + :C_COUNT

WHERE A. RDB$DB_KEY = : DBK;

END

Длительность действия

По умолчанию областью действия db key является текущая транзакция. Вы можете считать, что он остается правильным во время действия текущей транзакции. Подтверждение или откат транзакции приведет к тому, что значения RDB$DB_KEY станут непредсказуемыми. Если вы используете commitRetaining, контекст транзакции сохраняется, блокируя сборку мусора и, следовательно, предотвращая "переназначение" старого db_key. При этих условиях значения RDB$DB_KEY для любых используемых строк в вашей транзакции сохраняются действительными, пока не произойдет "жесткое" подтверждение или откат.

После жесткого подтверждения или отката другая транзакция может удалить строку, которая была изолирована внутри контекста вашей транзакции и, следовательно, рассматривалась как "существующая" в вашем приложении. Любое значение RDB$DB_KEY теперь может указывать на несуществующую строку. Если у вас достаточно большой интервал между моментом, когда начинается ваша транзакция и когда завершается ваша работа, вы должны проверять, не была ли за это время строка изменена или заблокирована другой транзакцией.

Некоторые интерфейсы приложений, например IB Objects, являются суперинтеллектуальными в плане добавлений и могут подготовить "сегмент" для вновь добавленных строк в клиентских буферах для быстрого обновления списка после подтверждения. Такие возможности важны для производительности при работе в сети. Однако "интеллектуальность", подобная этой, основывается на точных реальных ключах. Поскольку db_key является просто заменителем ключа для набора, наследуемого от предыдущих подтвержденных данных, он не имеет смысла для новой строки - он не доступен при изменениях в клиентском буфере.

  • Читать дальше
  • 1
  • ...
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: