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

Откуда: Киев
Сообщений: 155
Столкнулся с одной граблей. Запускаю элементарный справочник с парой полей всего. См. приложенную таблицу. Редактируется/удаляется/ добавляется все нормально и рузультаты изменений сохраняются нормально, кроме единственного случая. Про этот случай ниже. В чем прикол понять не могу.

При загрузке справочника создается локальная таблица идентичная той, кот. в базе:
SET DELETED ON
IF !USED('type')
	USE type IN 0 ORDER shortname
	CURSORSETPROP('buffering',5,'type')
ENDIF 

SELECT * FROM type ORDER BY typename, shortname INTO TABLE tmpType

При выходе из справочника идет сохранение результатов:
SET DELETED OFF 
&&	delete 
SELECT typeID FROM tmpType WHERE DELETED() INTO CURSOR crsTD
DELETE FROM type WHERE typeID in (SELECT typeID FROM crsTD)
TABLEUPDATE(.t.,.t.,'type')

&&	insert 
INSERT INTO type (typename, shortname, dataadd, dataedit, uaddid, ueditid) ;
	SELECT typename, shortname, dataadd, dataedit, uaddid, ueditid FROM tmpType as TD ;
		WHERE !DELETED() AND TD.typeID NOT in (SELECT typeID FROM type WHERE !DELETED())
TABLEUPDATE(.t.,.t.,'type')

&&	update
UPDATE type SET type.typename=tmpType.typename, type.shortname=tmpType.shortname ;
	FROM tmpType ;
	WHERE type.typeid = tmpType.typeid AND !DELETED() AND ;
		(type.shortname#tmpType.shortname	OR type.typename#tmpType.typename)
TABLEUPDATE(.t.,.t.,'type')

USE IN crsTD

SET DELETED ON 

Если в таблице физически нет ни одной записи или есть хоть одна без пометки deleted - сохранение проходит на ура. В случае, если в таблице есть только удаленные записи - записи в базу не добавляются. Т.е. во временной локальной таблице они есть, но insert-ом не вставляются.

Чтобы понять, отбираются ли записи для вставки смотрел часть insert-а, где отбираются записи для вставки:
SELECT typename, shortname, dataadd, dataedit, uaddid, ueditid FROM tmpType as TD ;
		WHERE !DELETED() AND TD.typeID NOT in (SELECT typeID FROM type WHERE !DELETED())

Данные выбираются правильно. Но не вставляются. Подозреваю, что дело может быть в этих !DELETED().

Где собака порылась, подскажите?
11 янв 08, 15:21    [5140991]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
lo-pata
Member

Откуда: Киев
Сообщений: 155
Странно, после того как вместо
SELECT typeID FROM type WHERE !DELETED()
в инсерте написал
SELECT typeID FROM type

Все заработало. Немного непонятно для меня.
11 янв 08, 15:40    [5141165]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Фокс какой?
11 янв 08, 15:47    [5141215]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
lo-pata
Member

Откуда: Киев
Сообщений: 155
9 sp1
11 янв 08, 15:48    [5141225]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
lo-pata
Member

Откуда: Киев
Сообщений: 155
Вот, кстати и сама таблица - не заметил, что сразу не прикрепилась.

К сообщению приложен файл (type.zip - 500bytes) cкачать
11 янв 08, 15:49    [5141238]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
При использовании нескольких таблиц-источников, как поведет себя функция Deleted() внутри команды Select-SQL заранее предсказать невозможно. Точнее, невозможно сказать, в каком алиасе он будет выполнять проверку признака удаленной записи.

Поэтому, в команде INSERT-SQL я бы посоветовал выбросить все условия по !Deleted(), а перед исполнением запроса просто вернуть настройку

SET DELETED ON

Ведь удаленные записи уже были удалены, значит, сохранять настройку OFF - нет необходимости.
11 янв 08, 16:05    [5141381]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
lo-pata
Member

Откуда: Киев
Сообщений: 155
ВладимирМ , почему-то о таком простом варианте - вернуть настройку после удаления - даже в голову не пришло. Но насчет алиаса - в этих же запросах ставил deleted() с указаниями конкретных алиасов, в которых они должны проверять условие - результат тот же.
11 янв 08, 16:13    [5141446]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
lo-pata
Member

Откуда: Киев
Сообщений: 155
Мои рассуждения: пусть пока остается
SELECT typeID FROM type WHERE !DELETED('type')
Дальше три варианта:
1. В таблице вообще нет записей - возвращается 0 записей
2. В таблице только удаленные записи - результат тоже 0
3. Есть неудаленные записи - непустой набор

Но при этом какая разница между вариантами 1 и 2? В первом случае insert проходит, во втором нет?

Убираем условие:
SELECT typeID FROM type
Снова три варианта:
1. получаем 0 записей
2. получаем непустой набор
3. тоже непустой набор

Работает во всех трех случаях.

Почему?
11 янв 08, 16:19    [5141499]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
lo-pata
Но насчет алиаса - в этих же запросах ставил deleted() с указаниями конкретных алиасов, в которых они должны проверять условие - результат тот же.

Так нельзя. Это не будет работать.

Дело в том, что внутри команды Select-SQL таблицы открываются в других, скрытых, рабочих областях. Отличных от тех, которые видны разработчику.

Это значит, что функция Deleted() при явном указании алиаса будет всегда ссылаться только на одну запись указанной рабочей области. Вот на какую запись попали, в указанной рабочей области, то значение Deleted() и вернет для ВСЕХ записей выборки.

Поэтому, функцию Deleted() лучше в запросах вообще не использовать. А если и использовать, то только в самых простых. И ни в коем случае не указывать явно алиас таблицы.
11 янв 08, 16:23    [5141548]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
CREATE CURSOR test (f1 I)
APPEND BLANK
DELETE
APPEND BLANK

* Встаем на запись, помеченную как удаленная
select test
go 1

* В выборке ничего нет
SELECT * FROM test WHERE !DELETED("test")

* Встаем на запись, НЕ помеченную как удаленная
select test
go 2

* В выборке две записи
SELECT * FROM test WHERE !DELETED("test")
11 янв 08, 16:28    [5141590]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение изменений  [new]
lo-pata
Member

Откуда: Киев
Сообщений: 155
Насчет явного указания алиаса запомню. Спасибо.
11 янв 08, 16:32    [5141626]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить