2012-04-18 6 views
1

У меня есть 6 столов:Нужна помощь в создании запроса в SQL?

Staff (StaffID, Name) 
Product (ProductID, Name) 
Faq (FaqID, Question, Answer, ProductID*) 
Customer (CustomerID, Name, Email) 
Ticket (TicketID, Problem, Status, Priority, LoggedTime, CustomerID* , ProductID*) 
TicketUpdate (TicketUpdateID, Message, UpdateTime, TicketID* , StaffID*) 

Вопрос дать ответ: Учитывая идентификатор продукта, удалить запись для этого продукта. Когда продукт удаляется, все связанные с ним часто задаваемые вопросы могут оставаться в базе данных, но должны иметь нулевую ссылку в поле ProductID. Однако удаление продукта должно также удалить любые связанные билеты и их обновления. Для полноты удаленных билетов и их обновлений следует скопировать в таблицу аудита или в набор таблиц, которые содержат исторические данные о продуктах, их билетах и ​​обновлениях. (Подсказка: вам нужно будет определить дополнительную таблицу или набор или таблицы для ведения этой информации аудита и автоматически скопировать любые удаленные билеты и обновления билетов при удалении продукта). Таблица аудита должна записывать пользователя, который запросил удаление, и отметку времени для операции удаления.

Я создал дополнительный maintain_audit таблицу:

CREATE TABLE maintain_audit(
TicketID INTEGER NOT NULL, 
TicketUpdateID INTEGER NOT NULL, 
Message VARCHAR(1000), 
mdate TIMESTAMP NOT NULL, 
muser VARCHAR(128), 
PRIMARY KEY (TicketID, TicketUpdateID) 
); 

Addittionally Я создал 1 функцию и триггер:

CREATE OR REPLACE FUNCTION maintain_audit() 
     RETURNS TRIGGER AS $BODY$ 
     BEGIN 
     INSERT INTO maintain_audit (TicketID,TicketUpdateID,Message,muser,mdate) 
    (SELECT Ticket.ID,TicketUpdate.ID,Message,user,now() FROM Ticket, TicketUpdate WHERE    Ticket.ID=TicketUpdate.TicketID AND Ticket.ProductID = OLD.ID); 
     RETURN OLD; 
     END; 
    $BODY$ 
     LANGUAGE plpgsql; 


CREATE TRIGGER maintain_audit 
    BEFORE DELETE 
    ON Product 
    FOR EACH ROW 
    EXECUTE PROCEDURE maintain_audit() 

    DELETE FROM Product WHERE Product.ID=30; 

Когда я запускаю это все, что я получаю это:

ERROR: null value in column "productid" violates not-null constraint 
    CONTEXT: SQL statement "UPDATE ONLY "public"."faq" SET "productid" = NULL WHERE $1  OPERATOR(pg_catalog.=) "productid"" 

GUYS, Не могли бы вы помочь мне в решении этой проблемы?

ответ

2

Возможно, вам нужны триггеры. Не знаете, какие RDBMS вы используете, но вот где вы должны начать. Я начал с нуля и запускал триггеры в несколько похожей ситуации в течение часа.

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

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

select * into destination from source where 1=0 

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

+0

Спасибо Джастин! ;-) Это очень полезно! – BlackOctober

1
  1. создать внешний ключ для Ticket.product_id и TicketUpdate.Ticket_id который имеет ON DELETE CASCADE. При удалении продукта автоматически удаляются все билеты и билеты.

  2. создать таблицу аудита для удаления продукта с помощью product_id, пользователя и метки времени. таблицы аудита для билета, ticketUpdate должен точно их отразить.

  3. создать ДОПОЛНИТЕЛЬНЫЙ ТРИГГЕР для таблицы Билет, который копирует билеты в таблицу аудита.

  4. Сделайте то же самое для TicketUpdate

  5. Создать ПОСЛЕ DETETE Trigger на продукты, чтобы захватить, попросивший продукт будет удален в таблице аудита продукт.

  6. В таблице FAQ создать PRODUCT_ID в качестве внешнего ключа с ON DELETE SET NULL

+0

Спасибо, Дэвид много! ;-) Это очень полезно! – BlackOctober