29 нояб. 2011 г.

Удалить все ограничения из базы данных

Приведенный ниже скрипт формирует список команд для удаления ограничений указанного типа из базы данных.
select
  'ALTER TABLE "' || trim(rdb$relation_name) || '" ' ||
  'DROP CONSTRAINT "' || trim(rdb$constraint_name) || '";'
from
  rdb$relation_constraints
where
  rdb$constraint_type in ('PRIMARY KEY', 'FOREIGN KEY')
order by
  rdb$constraint_type asc
Обратите внимание на сортировку. Внешние ключи должны удаляться перед первичными.

28 нояб. 2011 г.

Брюки превращаются, превращаются брюки...

Помните как там было, в Бриллиантовой руке: Легким движением руки брюки превращаются, превращаются брюки...

В Гедымине для некоторых классов возможно превращение экземпляров в объекты одного из родительских классов. Например, Физическое лицо может стать Сотрудником предприятия и наоборот. Рабочая организация — просто организацией. Естественно, что РУИД при таких метаморфозах сохраняется, а это влечет за собой проблемы при загрузке из потока. День убит на разборку такой ситуации: была рабочая организация, которая когда-то настройкой перенесена на другую базу. Впоследствии, на той базе она была удалена из списка рабочих организаций и стала просто компанией. Теперь, с очередной настройкой, эта же запись, все того же типа Рабочая организация и с тем же РУИДом, снова пытается загрузиться на базу. В процессе загрузки создается экземпляр TgdcOurCompany, который не видит уже существующую компанию, что дает основание механизму загрузки создать новый экземпляр и попытаться сохранить его в базе. При сохранении возникает исключение, так как в GD_CONTACT запись с таким ИД уже есть.

По хорошему, радикальное решение данной проблемы — это полный запрет на превращения типов. Т.е. гражданин Фунт не может стать зицпредседателем Фунтом. Он должен (ради чистоты парадигмы!) погибнуть и воскреснуть уже как ипостась другого класса и с новым РУИДом. Но, такое изменение может вылезти боком в местах, которые сейчас даже не представляется возможным предугадать.

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

Посчитать от 1 до N

Можно с помощью рекурсивного CTE:
with recursive enum as (
  select 1 as n from rdb$database
  union all
  select (e.n + 1) as n from enum e
  where e.n < :MAX_N
  )
select n from enum
Максимальное значение параметра :MAX_N ограничено внутренним лимитом сервера на выполнение рекурсивных запросов (несколько тысяч для FB 2.5).

Приведенный код не настолько бесполезен, как может показаться на первый взгляд. С его помощью можно реализовать поиск свободного идентификатора группы пользователей в таблице GD_USERGROUP:

select
  first 1 e.n
from
  gd_usergroup g right join (
    with recursive enum as (
      select 7 as n from rdb$database
      union all
      select (e.n + 1) as n from enum e
      where e.n < 32
      )
    select
      n
    from
      enum) e on e.n = g.id
where
  g.id is null
order by
  1
Пусть вас не смущает семерка в качестве начального числа счета — первые шесть групп стандартные и не могут быть удалены из таблицы.

26 нояб. 2011 г.

Новости наших партнеров

  • 15 ноября состоялся республиканский семинар: «Развитие информационной системы АПК Минской области. Автоматизация бухгалтерского учета как элемент внутрихозяйственной информационной системы».
  • Совещание 09.09.2011 в Управлении сельского хозяйства и продовольствия Любанского райисполкома, посвященное вопросам внедрения и эксплуатации программного комплекса "НИВА-СХП:Бизнес-план".
  • Постоянно действующие тематические консультационно-практические обучающие семинары по ТПК "НИВА-СХП".
  • История обновлений ТПК "НИВА-СХП".
  • Список сертифицированных специалистов по внедрению ТПК "НИВА-СХП" и дистанционная система сертификации.

17 нояб. 2011 г.

100% clean

FileCluster проверил нашу уилиту FDBConvert четырьмя антивирусами и выдал такой бэдж:

FDBConvert antivirus report at FileCluster.com

13 нояб. 2011 г.

Обо всем

  • Наводнение в Тайланде стало серьезной преградой к обновлению офисного рабочего сервера. Четыре 2Тб винчестера на сегодняшний день стоят не намного меньше, чем весь компьютер в сборе еще пару месяцев назад. Печально, что восстановление производства не обещают ранее конца 1 кв следующего года.
  • Краткий курс SQL уже имеет более 100 000 просмотров. К моему стыду, в интернете выложен недоработанный, неоконченный вариант. По сути, черновик. Надо будет разобраться с очередной группой и существенно переделать его. Идея краткого (по настоящему краткого, а не "Освой SQL за 21 день") курса родилась во времена регулярных занятий с сотрудниками ГИВЦа, где действовал жесткий временной лимит — не более 1-1,5 часа раз в неделю.
  • Наша текущая разработка под Windows CE 5 — терминал кладовщика на основе Datalogic Skorpio, является первым нашим true open source продуктом. Не только весь ее исходный код доступен, но и для компиляции используется Free Pascal.
  • Необходимость сделать дубликат 2Тб винчестера выявила полное превосходство бесплатного софта в этом сегменте над платными аналогами. Сначала Nero не смог создать загрузочный DVD из ISO образа Clone Zilla. Размер ISO был небольшим и Nero настойчиво требовал предоставить ему болванку именно формата CD-R. Где сейчас такую найдешь? Infra Recorder справился с задачей не задумываясь.

    Встроенная в Windows Server 2003 R2 утилита архивного копирования не имеет опции для отключения сжатия данных. И это только пол беды, так как используемые ею алгоритмы настолько небыстры, что для сжатия 1.8 Тб по оценке требуется 3-4 суток. FBackup (без сжатия) справился с задачей за одну ночь.

  • Так получилось, что окно О программе обновлялось нерегулярно. В результате, некоторые люди незаслуженно "выпали" из когорты причастных к Гедымину. Восстановленный полный список выглядит так:

Порядок не алфавитный и не всегда хронологический. Вспомните еще кого, пишите в комментарии.

8 нояб. 2011 г.

USING INDEX

Век живи — век учись. Оказывается, уже начиная с версии 1.5 в Firebird можно именовать индексы ограничений и указывать их сортировку. Синтаксис соответствующей команды:
[CONSTRAINT constraint-name]
   <constraint-type> <constraint-definition>
   [USING [ASC[ENDING] | DESC[ENDING]] INDEX index_name]
В Гедымине мы используем суррогатные целочисленные первичные ключи. Идентификатор конкретной записи уникален в пределах всех таблиц базы и является положительным числом. Никакого дополнительного смысла в идентификатор не вкладывается, за исключением диапазона от 0 до 146999999, зарезервированного для системных объектов.

Дополнительный смысл — иными словами говоря функциональная зависимость первичного ключа от некоторого поля (полей) записи помогла бы ускорить выполнение некоторых запросов и уменьшить размер базы данных. Вот несколько возможных случаев:

  • Для таблицы gd_document присваивать идентификатор в соответствии с хронологией документов. Тогда сортировка по дате и выборка за период (две наиболее частых операции со списком документов) будут выполняться с использованием индекса первичного ключа, который и так всегда под рукой у оптимизатора для соединений с дополнительными таблицами. Для быстрой выборки за период можно держать под рукой соответствие начальных ИД на каждую дату.
  • Идентификатор для интервальных деревьев присваивать в соответствии с порядковым номером узла при обходе дерева вглубь. Отпадает необходимость в полях LB, RB. Интервал для дочерних элементов будет определяться как разность между ИД соседних узлов. Для совместимости с существующим кодом можно ввести вычисляемые поля LB (просто будет возвращать значение идентификатора записи) и RB (идентификатор следующей записи на этом же уровне минус единица).
  • Для складских карточек (таблица INV_CARD) присваивать идентификатор в соответствии с очередностью цепочки, заменив поле parent на признак первой карточки в последовательности.
  • и т.д.
Можно сказать, что идет речь о симуляции кластерного индекса для таблиц, абсолютное большинство запросов к которым требует сортировки по определенному полю и/или отсечению заданного диапазона значений. Разумеется, что множество значений рассматриваемого поля должно быть линейно упорядоченным.

Основная проблема реализации такой концепции — это вставка идентификатора внутрь существующей цепочки. При отсутствии свободного промежутка придется сдвигать все идентификаторы вправо, что может вызвать цепную реакцию — каскадное обновление огромного количества записей в базе (представьте сдвиг вправо нескольких миллионов записей в таблице gd_document, к которым привязаны дополнительные таблицы документов, бухгалтерские проводки и складское движение). Мы можем минимизировать последствия, если:

  • Откажемся от единого на всю базу генератора gd_g_unique в пользу выделенного генератора для каждой таблицы. Будем формировать идентификаторы с шагом 10 (для менее населенных таблиц можно использовать шаг 100 и даже 1000).
  • Вместо сдвига всего правого поддиапазона относительно вставляемой записи будем выискивать свободные места и перемещать отдельные "кусочки".

7 нояб. 2011 г.

Новый клип Ляписа

Сто лет прошло, а ситуация в Беларуси точь-в-точь как во времена Янки Купалы. Ничего не изменилось.

Кто не заметил, на вышыванках у Михалка и Булатникова пиктограммка Гедымина ))

3 нояб. 2011 г.

RSS для форумов

Немного возьни с PHP (тот еще язык, надо заметить) и теперь у нас есть отдельный канал для форумов. Настраивайте свои читалки на gsbelarus.com/gs/backend_forums.php.

Не могу не прорекламировать: dlvr.it -- сервис трансляции RSS или Atom каналов в социальные сети. В т.ч. поддерживается твиттер.

2 нояб. 2011 г.

Очередная группа и запорченное фото

Ужасные условия для фотографирования в нашей аудитории. Тем не менее, как есть, так есть. Очередная группа прошла обучение.
Специалисты Гомельобоев, Сморгонского КХП, Гродненского Гаранта, преподаватели Новопольского колледжа и др.