2009-05-01 2 views
5

Можно ли предотвратить удаление первой строки в таблице на стороне PostgreSQL?Как предотвратить удаление первой строки в таблице (PostgreSQL)?

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

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

ответ

6

Лучшим способом я вижу, для достижения этой цели является созданием удаления триггера на этой таблице. В принципе, вам придется написать хранимую процедуру, чтобы убедиться, что эта категория «по умолчанию» всегда существует, а затем принудительно применяет ее, используя событие триггера ON DELETE в этой таблице. Хороший способ сделать это - создать триггер для каждой строки, который гарантирует, что в событиях DELETE строка категории по умолчанию никогда не будет удалена.

Пожалуйста, ознакомьтесь с документацией PostgreSQL по поводу триггеров и хранимых процедур:

http://www.postgresql.org/docs/8.3/interactive/trigger-definition.html

http://www.postgresql.org/docs/8.3/interactive/plpgsql.html

Там также ценные примеры в этой вики:

http://wiki.postgresql.org/wiki/A_Brief_Real-world_Trigger_Example

9

Вы хотите определить ПЕРЕД УДАЛЕНИЕМ trigger на столе. Когда вы пытаетесь удалить строку (либо по PK, либо иметь отдельный «защищенный» логический столбец), RAISE - исключение.

Я не знаком с синтаксисом PostgreSQL, но it looks like это то, как вы могли бы сделать это:

CREATE FUNCTION check_del_cat() RETURNS trigger AS $check_del_cat$ 
    BEGIN    
     IF OLD.ID = 1 /*substitute primary key value for your row*/ THEN 
      RAISE EXCEPTION 'cannot delete default category'; 
     END IF; 

    END; 
$check_del_cat$ LANGUAGE plpgsql; 

CREATE TRIGGER check_del_cat BEFORE DELETE ON categories /*table name*/ 
    FOR EACH ROW EXECUTE PROCEDURE check_del_cat(); 
+0

Спасибо за ваш ответ. И вы, и Macalendas дали полезные ответы, поэтому было сложно выбрать «принятый» ответ, но я решил отдать его Macalendas, чтобы поощрять новых пользователей к участию в этом удивительном сайте. Спасибо! –

+0

Без проблем и радости я мог бы помочь. Я также просто закрыл несоответствие цитата в теге , так что ссылки должны работать правильно. –

9

Вы были правы, думая о системе правил. Here - это ссылка на пример, соответствующий вашей проблеме. Это даже проще, чем триггеры:

create rule protect_first_entry_update as 
    on update to your_table 
    where old.id = your_id 
    do instead nothing; 
create rule protect_first_entry_delete as 
    on delete to your_table 
    where old.id = your_id 
    do instead nothing; 

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

+0

не уверен, почему этот ответ не получает больше любви, но правила защиты потрясающие!: +1: –

0

Имейте в виду, как работают триггеры. Они будут сбрасываться для каждой строки, которую удалит оператор delete. Это не означает, что вы не должны использовать триггеры, просто помните об этом и, самое главное, проверяйте свои сценарии использования и убедитесь, что производительность соответствует требованиям.

Должен ли я использовать правило или триггер?

От официальных документов: «Для вещей, которые могут быть реализованы обоими, что лучше всего зависит от использования базы данных. Триггер запускается для любой затронутой строки один раз. Правило манипулирует запросом или генерирует дополнительный запрос. Поэтому, если в одном из операторов затронуто несколько строк, правило, выдающее одну дополнительную команду, скорее всего будет быстрее, чем триггер, который вызывается для каждой отдельной строки и должен выполнять свои операции много раз.Однако триггер подход концептуально гораздо проще, чем правила подход, и проще для новичков, чтобы получить право.»

Смотрите документацию для деталей.
http://www.postgresql.org/docs/8.3/interactive/rules-triggers.html