Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / FoxPro, Visual FoxPro Новый топик    Ответить
 Cascade удаление удаляет не все записи?!  [new]
Лисонька
Member

Откуда:
Сообщений: 294
Леди и джентльмены!
Заметила этот свой недочет в проекте лишь сегодня и была озадачена. Объясняю в общих чертах.
Table1: nIdCod, cFio, cAdres. Primary индекс на nIdCod.
Table2: nId, nIdCod, dDate, cComment. Primary индекс на nId, Regular на nIdCod.
В DB Disigner установлен Relationship "один ко многим" от Table1 к Table2 по индексам на nIdCod. Когда делаю триггер, получается, что Table1 является Parent, а Table2 - Child, на Delete выставлено Cascade. Как я рассчитывала, при удалении записи в Table1 из Table2 должны удаляться все записи с таким же nIdCod. А сегодня заглянула в таблицу и очень удивилась. В Table2 всегда после удаления остается 1 запись из тех, которые, по идее, должны каскадно удалитсья при удалении родительской записи.
Извините, что так путанно объясняю пробему. Но кто догадался, что я хотела сказать, посоветуйте.
Благодарю.
6 июл 06, 12:14    [2849156]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Пиведите, код при удалении, желательно так как он у Вас реализован, а не пример кода.
6 июл 06, 12:34    [2849292]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
Станислав С
Guest
Лисонька
Леди и джентльмены!
Заметила этот свой недочет в проекте лишь сегодня и была озадачена. Объясняю в общих чертах.
Table1: nIdCod, cFio, cAdres. Primary индекс на nIdCod.
Table2: nId, nIdCod, dDate, cComment. Primary индекс на nId, Regular на nIdCod.
В DB Disigner установлен Relationship "один ко многим" от Table1 к Table2 по индексам на nIdCod. Когда делаю триггер, получается, что Table1 является Parent, а Table2 - Child, на Delete выставлено Cascade. Как я рассчитывала, при удалении записи в Table1 из Table2 должны удаляться все записи с таким же nIdCod. А сегодня заглянула в таблицу и очень удивилась. В Table2 всегда после удаления остается 1 запись из тех, которые, по идее, должны каскадно удалитсья при удалении родительской записи.
Извините, что так путанно объясняю пробему. Но кто догадался, что я хотела сказать, посоветуйте.
Благодарю.

Сделай процедуру по поиску "провисших ссылок" (т.е. таблица2-parent, а таблица1-Child) и удаляй из таблицы2 те записи, для которых нет "пары" в таблице1. поставь эту процедуру в раздел "Администрирование" и запускай периодически....
6 июл 06, 12:41    [2849348]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
Какая версия FoxPro?

Приведи код процедуры каскадного удаления. Это в хранимых процедурах, начинается с

procedure RIDELETE

В некоторых версиях VFP там была ошибка, а кроме того, этот код может не сработать при определенных условиях.
6 июл 06, 12:47    [2849386]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
Лисонька
Member

Откуда:
Сообщений: 294
PaulWist
Пиведите, код при удалении, желательно так как он у Вас реализован, а не пример кода.

** Это в Loade**
= CURSORSETPROP('Buffering', 5, 'Table1')

** Это на KeyPress кнопки  **
   SELECT Table1
   REPLACE Table1.cFio WITH ALLTRIM(STR(Table1.nIdCod,6,0))    && Может и лишнее, но делаю для того, чтобы, если; 
                                                                                                         пользователям вновь придется внести этого же человека, ;
                                                                                                         на нарушилась уникальность другого индека этой же таблицы
   REPLACE Table1.cAdres WITH ALLTRIM(STR(Table1.nIdCod,6,0))
   ........
   DELETE 
   GO TOP IN Table1
   =TABLEUPDATE(.t.)
автор
Сделай процедуру по поиску "провисших ссылок" (т.е. таблица2-parent, а таблица1-Child) и удаляй из таблицы2 те записи, для которых нет "пары" в таблице1. поставь эту процедуру в раздел "Администрирование" и запускай периодически....

Можно и код написать на удаление по nIdCod, но почему триггер так работает?
автор
Какая версия FoxPro?
Приведи код процедуры каскадного удаления. Это в хранимых процедурах, начинается с
procedure RIDELETE
В некоторых версиях VFP там была ошибка, а кроме того, этот код может не сработать при определенных условиях.

Вроде бы выслала то, что Вы попросили.

К сообщению приложен файл (Триггер.rtf - 2Kb) cкачать
6 июл 06, 13:45    [2849742]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
Это не то.

Это текста собственно триггера, но внутри себя он вызывает другую процедуру вот этой командой

llRetVal=ridelete()

Так вот, RIDELETE - это процедура созданная там же. Она как раз и обеспечивает сам факт удаления.

А триггер __RI_DELETE_table1 - это по сути, просто цикл, который перебирает все записи, которые он планирует удалить и вызывает для удаления функцию RIDELETE(). Вот код этой самой функции и хотелось бы посмотреть.
6 июл 06, 14:11    [2849907]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
Лисонька
Member

Откуда:
Сообщений: 294
ВладимирМ
Это не то.
Это текста собственно триггера, но внутри себя он вызывает другую процедуру вот этой командой
llRetVal=ridelete()
Так вот, RIDELETE - это процедура созданная там же. Она как раз и обеспечивает сам факт удаления.
А триггер __RI_DELETE_table1 - это по сути, просто цикл, который перебирает все записи, которые он планирует удалить и вызывает для удаления функцию RIDELETE(). Вот код этой самой функции и хотелось бы посмотреть.

Уважаемый Гуру!
Я приношу свои извинения, но значить я попросту не знаю, где находится процедура RIDELETE. Поскольку по поиску в Stored Procedure этого слова я не нахожу, значит, процедура прописана где-то еще. Вопрос: а где тогда ее можно посмотреть, скопировать и выложить на форум?
Благодарю.
6 июл 06, 14:40    [2850072]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
RIDELETE вообще-то одна из самых первых после фразы

**__RI_HEADER!@ Do NOT REMOVE or MODIFY this line!!!! @!__RI_HEADER**

Однако если ее не нашли, то как же вообще триггер работает? Ведь в присланном фрагменте явно прописан ее вызов

llRetVal=ridelete()

Попробуй сделать тестовую базу с 2 таблицам и создай для них триггер на удаление по типу Cascade.

Кроме того, команду TableUpdate() "в никуда" давать просто нельзя. Как же отлавливать возможные ошибки? Как минимум, нужно так:

IF TableUpdate(.T.) = .F.
	LOCAL laError(1)
	=AERROR(laError)
	IF laError[1,1] = 1539 && ошибка триггера
		* Смотрим глобальный массив gaErrors
		* Этот массив создается и напоняется внутри тела триггера 
		* и содержит причину возникновения ошибки
	ENDIF
ENDIF
6 июл 06, 14:49    [2850157]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
В дополнение, поскольку идет каскадное обновление FK, не мешало бы обернуть модификацию в транзакцию.


ВладимирМ

Кстати, на View такой фокус не прошел бы.

REPLACE Table1.cAdres WITH ALLTRIM(STR(Table1.nIdCod,6,0))
   ........
   DELETE
   GO TOP IN Table1
   =TABLEUPDATE(.t.)
6 июл 06, 15:00    [2850261]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
Лисонька
Member

Откуда:
Сообщений: 294
Сделала БД из двух таблиц. Выставила триггер. Та же история. Сегодня утром проделала эту процедуру на другом компьютере. Там все нормально (фоксовый дитрибутив на машинах один и тот же). Тогда я снесла Фокс у себя и инсталльнула заново. В проекте заново расставила триггеры. И все заработало. Появился код:
procedure RIDELETE
local llRetVal
llRetVal=.t.
 IF (ISRLOCKED() and !deleted()) OR !RLOCK()
    llRetVal=.F.
  ELSE
    IF !deleted()
      DELETE
      IF CURSORGETPROP('BUFFERING') > 1
      	=TABLEUPDATE()
      ENDIF
    ENDIF not already deleted
  ENDIF
  UNLOCK RECORD (RECNO())
  llRetVal=pnerror=0
RETURN llRetVal
Благодарю всех-всех-всех!

Елизавета Скрунскайте
7 июл 06, 10:01    [2852781]     Ответить | Цитировать Сообщить модератору
 Re: Cascade удаление удаляет не все записи?!  [new]
Лисонька
Member

Откуда:
Сообщений: 294
ВладимирМ
Кроме того, команду TableUpdate() "в никуда" давать просто нельзя.

Каюсь, Учитель!.. Вы же мне еще месяца два назад попеняли на эту "безадресность". Я везде в проекте переправила, а про кнопку для удаления не подумала (((
7 июл 06, 11:36    [2853442]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить