Удаление старых записей
Удаление старых записей
Добрый день
Точно знаю что вопрос дико ламерский, что я где-то туплю, но как сделать такую простую с виду вещь
DELETE FROM MAIN WHERE MAIN.ID_REC>0 AND MAIN.DATE_CR<'01.12.2008'
Если делаю DELETE FROM MAIN WHERE MAIN.ID_REC=1 например то запись удаляется. Но мне нужно прочистить всё, оставив первую запись и последние несколько рабочих месяцев.
Точно знаю что вопрос дико ламерский, что я где-то туплю, но как сделать такую простую с виду вещь
DELETE FROM MAIN WHERE MAIN.ID_REC>0 AND MAIN.DATE_CR<'01.12.2008'
Если делаю DELETE FROM MAIN WHERE MAIN.ID_REC=1 например то запись удаляется. Но мне нужно прочистить всё, оставив первую запись и последние несколько рабочих месяцев.
Re: Удаление старых записей
и что не устраивает в приведенном операторе?
DELETE FROM MAIN WHERE MAIN.ID_REC>0 AND MAIN.DATE_CR<'01.12.2008'
Re: Удаление старых записей
Ну, что-то не устраивает
SQL> DELETE FROM MAIN
CON> WHERE (MAIN.ID_REC>0) and (MAIN.DATE_CR<'01.12.2008');
Statement failed, SQLCODE = -508
no current record for fetch operation
-attempted update of read-only column
В таблице MAIN 892 записи
Триггеры на удаление не влияют, по одной записи удаляется легко и непринуждённо.
SQL> DELETE FROM MAIN
CON> WHERE (MAIN.ID_REC>0) and (MAIN.DATE_CR<'01.12.2008');
Statement failed, SQLCODE = -508
no current record for fetch operation
-attempted update of read-only column
В таблице MAIN 892 записи
Код: Выделить всё
SQL> show table main;
ID_REC INTEGER Not Null
ID_PARENT INTEGER Not Null DEFAULT -1
JARLIK (D_JARLIK) VARCHAR(15) Nullable
DATE_CR DATE Not Null DEFAULT 'NOW'
TIME_CR TIME Not Null DEFAULT 'NOW'
ID_BAG INTEGER Not Null DEFAULT 1
ID_KAT INTEGER Not Null DEFAULT 0
ID_OBJ INTEGER Not Null DEFAULT 0
ID_STATE INTEGER Not Null DEFAULT 0
INDEX_OTP (D_INDEX) INTEGER Not Null DEFAULT 0
INDEX_POL (D_INDEX) INTEGER Not Null DEFAULT 0
INDEX_NEXT (D_INDEX) INTEGER Not Null DEFAULT 0
INDEX_PREV (D_INDEX) INTEGER Not Null DEFAULT 0
ID_USER INTEGER Not Null DEFAULT 0
ID_PLACE INTEGER Not Null DEFAULT 0
ID_ROUTE INTEGER Not Null DEFAULT 0
MASSA INTEGER Not Null DEFAULT 0
RECIEVED INTEGER Not Null DEFAULT 0
OLD_PARENT INTEGER Not Null DEFAULT 0
TR_TIP CHAR(1) Nullable
TR_NOMER VARCHAR(10) Nullable
TR_FIO VARCHAR(60) Nullable
CONSTRAINT PK_MAIN:
Primary key (ID_REC)
Triggers on Table MAIN:
MAIN_BIUD0, Sequence: 0, Type: BEFORE INSERT OR UPDATE OR DELETE, Active
MAIN_AIUD0, Sequence: 0, Type: AFTER INSERT OR UPDATE OR DELETE, Active
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Re: Удаление старых записей
Значит всё-таки влияют, просто по одной ты не добираешься до записи, на которой запрос обламывается. Не нужно в after-триггерах присваивать что-то new или old. А в before-триггерах - только old.
Re: Удаление старых записей
Вот первый триггер, который before
Вот второй, который after
Что тут может мешать? Думаю ещё backup/restore сделать, а то такое поведение гнусно пахнет.
Код: Выделить всё
AS
BEGIN
IF (INSERTING) THEN
BEGIN
IF (NEW.ID_REC IS NULL) THEN NEW.ID_REC = GEN_ID(GEN_MAIN_ID,1);
IF (NEW.ID_STATE BETWEEN 301 AND 302) THEN NEW.RECIEVED=1;
END
IF (UPDATING) THEN
BEGIN
IF (NEW.MASSA<0) THEN NEW.MASSA=0;
IF (NEW.ID_STATE=102) THEN
BEGIN
NEW.RECIEVED=1;
IF (OLD.ID_STATE<>101) THEN
BEGIN
NEW.ID_STATE=OLD.ID_STATE;
END
END ELSE
BEGIN
IF ((OLD.ID_STATE=101) AND ((NEW.ID_BAG=1) OR (NEW.ID_BAG=2))) THEN
BEGIN
NEW.OLD_PARENT=OLD.ID_PARENT;
END
IF (NEW.ID_STATE=501) THEN
BEGIN
IF ((NEW.RECIEVED=0) OR (NEW.ID_BAG<>1)) THEN NEW.ID_STATE=OLD.ID_STATE;
END
IF ((NEW.ID_STATE=1) AND (NEW.ID_BAG=2)) THEN NEW.ID_PARENT=0;
IF (NEW.ID_STATE IN (401,402,403)) THEN
BEGIN
IF ((NEW.ID_BAG=2) AND (NEW.ID_PARENT<=0)) THEN
BEGIN
NEW.ID_STATE=OLD.ID_STATE;
END
END
END
END
END
Код: Выделить всё
AS
BEGIN
IF (INSERTING) THEN
BEGIN
INSERT INTO MOVE (ID_MAIN, ID_OPER, ID_USER)
VALUES (NEW.ID_REC, NEW.ID_STATE, NEW.ID_USER);
IF ((NEW.ID_PARENT>0) AND (NEW.MASSA>0)) THEN
BEGIN
UPDATE MAIN SET MASSA=MASSA+NEW.MASSA WHERE ID_REC=NEW.ID_PARENT;
END
END
IF (UPDATING) THEN
BEGIN
IF (NEW.ID_PARENT<>OLD.ID_PARENT) THEN
BEGIN
IF (NEW.ID_PARENT>0) THEN
BEGIN
IF (NEW.MASSA>0) THEN
BEGIN
UPDATE MAIN SET MASSA=MASSA+NEW.MASSA WHERE ID_REC=NEW.ID_PARENT;
END
END
IF (OLD.ID_PARENT>0) THEN
BEGIN
IF (OLD.MASSA>0) THEN
BEGIN
UPDATE MAIN SET MASSA=MASSA-OLD.MASSA WHERE ID_REC=OLD.ID_PARENT;
END
END
END ELSE
BEGIN
IF ((NEW.MASSA<>OLD.MASSA) AND (NEW.ID_PARENT>0)) THEN
BEGIN
UPDATE MAIN SET MASSA=(MASSA-OLD.MASSA+NEW.MASSA)
WHERE ID_REC=NEW.ID_PARENT;
END
END
IF ((NEW.ID_STATE<>OLD.ID_STATE) AND (NEW.ID_STATE<>-1)) THEN
BEGIN
INSERT INTO MOVE (ID_MAIN, ID_OPER, ID_USER)
VALUES (NEW.ID_REC, NEW.ID_STATE, NEW.ID_USER);
IF (NEW.ID_STATE=1) THEN
BEGIN
IF (NEW.ID_BAG=2) THEN
UPDATE MAIN SET ID_PARENT=OLD.ID_PARENT WHERE ID_PARENT=NEW.ID_REC;
IF (NEW.ID_BAG=3) THEN
BEGIN
IF (NEW.ID_KAT=3) THEN
BEGIN
UPDATE MAIN SET ID_PARENT=0, ID_STATE=0 WHERE ID_PARENT=NEW.ID_REC;
END ELSE
BEGIN
UPDATE MAIN SET ID_PARENT=0 WHERE ID_PARENT=NEW.ID_REC;
END
END
END ELSE
BEGIN
IF (NEW.ID_STATE=498) THEN
UPDATE MAIN SET ID_STATE=NEW.ID_STATE, INDEX_PREV=NEW.INDEX_PREV,
INDEX_NEXT=NEW.INDEX_NEXT
WHERE ID_PARENT=NEW.ID_REC;
IF (NEW.ID_STATE<>498) THEN
UPDATE MAIN SET ID_STATE=NEW.ID_STATE WHERE ID_PARENT=NEW.ID_REC;
IF ((NEW.ID_STATE BETWEEN 501 AND 503) AND (NEW.ID_BAG=1)) THEN
BEGIN
UPDATE DESC_PO
SET NOMER_IZV=(SELECT MAX(D.NOMER_IZV)+1 FROM DESC_PO D)
WHERE ID_MAIN=NEW.ID_REC;
END
END
END
IF ((NEW.RECIEVED=1) AND (OLD.RECIEVED=0) AND (OLD.ID_STATE<>101)) THEN
BEGIN
INSERT INTO MOVE (ID_MAIN, ID_OPER, ID_USER)
VALUES (NEW.ID_REC, 102, NEW.ID_USER);
UPDATE MAIN SET ID_STATE=102 WHERE OLD_PARENT=NEW.ID_REC;
END
END
IF (DELETING) THEN
BEGIN
DELETE FROM DESC_PO WHERE ID_MAIN=OLD.ID_REC;
DELETE FROM MOVE WHERE ID_MAIN=OLD.ID_REC;
DELETE FROM MAIN WHERE ID_PARENT=OLD.ID_REC;
IF ((OLD.ID_PARENT>0) AND (OLD.MASSA>0)) THEN
BEGIN
UPDATE MAIN SET MASSA=MASSA-OLD.MASSA WHERE ID_REC=OLD.ID_PARENT;
END
END
IF ((OLD.ID_STATE BETWEEN 101 AND 199) OR
(NEW.ID_STATE BETWEEN 101 AND 199)) THEN POST_EVENT 'REFRESH_PRIEM';
IF ((OLD.ID_STATE BETWEEN 201 AND 299) OR
(NEW.ID_STATE BETWEEN 201 AND 299)) THEN POST_EVENT 'REFRESH_OBRIN';
IF ((OLD.ID_STATE BETWEEN 301 AND 399) OR
(NEW.ID_STATE BETWEEN 301 AND 399)) THEN POST_EVENT 'REFRESH_OBROUT';
IF ((OLD.ID_STATE BETWEEN 401 AND 499) OR
(NEW.ID_STATE BETWEEN 401 AND 499)) THEN POST_EVENT 'REFRESH_OTPR';
IF ((OLD.ID_STATE BETWEEN 501 AND 599) OR
(NEW.ID_STATE BETWEEN 501 AND 599)) THEN POST_EVENT 'REFRESH_DOST';
END
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Re: Удаление старых записей
А теперь копай вглубь, проверяй весь каскад по ветке
PS: Попытка апдейта только что удалённой родительской записи выглядит готичненько...
Код: Выделить всё
IF (DELETING) THEN
BEGIN
DELETE FROM DESC_PO WHERE ID_MAIN=OLD.ID_REC;
DELETE FROM MOVE WHERE ID_MAIN=OLD.ID_REC;
DELETE FROM MAIN WHERE ID_PARENT=OLD.ID_REC;
IF ((OLD.ID_PARENT>0) AND (OLD.MASSA>0)) THEN
BEGIN
UPDATE MAIN SET MASSA=MASSA-OLD.MASSA WHERE ID_REC=OLD.ID_PARENT;
END
END