Хобрук: Ваш путь к мастерству в программировании

триггер для проверки значения

У меня есть две таблицы:

create table building(
    id integer,
    name varchar(15),
    rooms_num integer,
    primary key(id)
);
create table room(
    id integer,
    building_id integer,
    primary key(id),
    foreign key(building_id) references building(id)
);

как видите, в таблице building есть поле rooms_num, которое показывает количество комнат в этом здании, и поле building_id в таблице room, которое показывает здание этой комнаты. Все, что я хочу, это чтобы, когда я вставляю значение в таблицу room, база данных проверяла себя и смотрела, не выходит ли за пределы допустимое количество комнат. не лучше ли кодировать его с помощью триггера? я пробовал это, но я не знаю, что указать в части условия:

CREATE TRIGGER onRoom
ON room 
BEFORE INSERT
????
23.12.2019

  • Возможно, вам придется лучше объяснить свои намерения. Что вы имеете в виду под номером комнаты за пределами границ? Какой номер комнаты? Внешний ключ к зданию гарантирует, что здание существует, а идентификатор в комнате является первичным ключом (возможно, последовательностью) и, следовательно, никогда не повторяется. Это не может быть номер комнаты в здании. 23.12.2019
  • не храните информацию, которую можно вычислить из существующих данных. Вам не нужен столбец room_num, потому что вы всегда можете вычислить текущий номер из таблицы комнат. 23.12.2019
  • Ах. Я застрял на номере комнаты - я полагаю, это должно быть количество комнат? То есть - подсчитать количество комнат, прописанных в здании. Извините - должно быть сезон. 23.12.2019
  • Вот ответ на аналогичный вопрос. Многие другие вокруг. stackoverflow.com/questions/1743439/ 23.12.2019

Ответы:


1

Сначала вы должны подтянуть свою модель данных. Все, что должно присутствовать, должно быть помечено NOT NULL, например, название здания. Мне нравится следить за тем, чтобы в обязательных текстовых полях были фактические значения, поэтому я устанавливаю ограничение проверки, которое соответствует хотя бы одному символу «слово» (буквенно-цифровому).

Вы никогда не должны разрешать отрицательные номера комнат, верно? Кроме того, вам следует избегать использования информации из частной базы данных, такой как номер комнаты или номер здания, в качестве первичного ключа. Его следует рассматривать только как ключ-кандидат. На мой взгляд, лучшей практикой было бы использовать UUID для первичных ключей., но некоторым людям нравятся автоматически увеличивающиеся целые числа, поэтому я не буду здесь настаивать. Дело в том, что комнаты, как правило, (например) отделяют их гипсокартоном или снимают, чтобы увеличить пространство. Переключение идентификаторов первичного ключа может привести к неожиданным результатам. Лучше отделить то, как он идентифицируется в базе данных, от самих данных, чтобы вы могли добавить «Комната 6А».

Также следует с уверенностью сказать, что у вас не будет более 32 767 комнат в здании, поэтому здесь подойдет int2 (16-битное, 2-байтовое целое).

CREATE TABLE building (
    id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name varchar(15) NOT NULL UNIQUE CHECK (name ~ '\w'),
    rooms_num int2 NOT NULL CHECK (rooms_num >= 0)
);

CREATE TABLE room (
    id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    -- Should there be a room name too?
    room_id int2 NOT NULL CHECK (room_id > 0),
    building_id integer NOT NULL REFERENCES building (id),
    UNIQUE (room_id, building_id)
);

Хорошо, теперь у вас есть более прочная основа для работы. Сделаем триггер.

CREATE FUNCTION room_in_building ()
RETURNS TRIGGER LANGUAGE plpgsql STRICT STABLE AS $$
BEGIN
  IF (
    -- We can safely just check upper bounds because the check constraint on
    -- the table prevents zero or negative values.
    SELECT b.rooms_num >= NEW.room_id
    FROM building AS b
    WHERE b.id = NEW.building_id
  ) THEN
    RETURN NEW; -- Everything looks good
  ELSE
    RAISE EXCEPTION 'Room number (%) out of bounds', NEW.id;
  END IF;
END;
$$;

CREATE TRIGGER valid_room_number
  BEFORE INSERT OR UPDATE -- Updates shouldn't break the data model either
  ON room
  FOR EACH ROW EXECUTE PROCEDURE room_in_building();

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

23.12.2019
Новые материалы

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

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

Обзор: Машинное обучение: классификация
Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

Разработка расширений Qlik Sense с qExt
Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..

React Hooks: основы деструктуризации массива
Kent C. Dodds написал классный пост о том, как грядущая функция React под названием Hooks работает на капоте. Предстоящий хук React useState основан на деструктурировании массива, давайте..

Пакеты R, используемые в Tesla
Добро пожаловать обратно! R — очень популярный язык программирования, используемый множеством компаний, включая Tesla! Итак, давайте взглянем на некоторые пакеты R, которые использует Tesla...

Сокращение и слияние токенов для эффективных моделей VL: обзор
Часто в задачах, связанных с компьютерным зрением и НЛП, вычислительно затратная и требующая большого объема памяти обработка становится препятствием для более быстрого логического вывода модели, а..