Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / FoxPro, Visual FoxPro Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Replace, Delete in Transaction  [new]
Sea.s2
Guest
Hi alles
Значит хочу записать мусор в одно из полей перед удалением
Появилась проблема если я делаю Replace потом Delete и затем TableUpdate в transaction то replace не updat'ится только удаляется запись тогда я сделал 2 транзакции. Вопрос можно так делать или как заставить до первого tableupdate сделать и Replace и Delete. Спасибо!
      ……..
      REPLACE &lcAlias .&tcField1 WITH “TT”
      BEGIN TRANSACTION       
      IF TABLEUPDATE(.F., .T., lcAlias) = .T.
        BEGIN TRANSACTION
        DELETE IN &lcAlias
        IF TABLEUPDATE(.F., .T., lcAlias) = .T.
          END TRANSACTION
          END TRANSACTION
         ………
        ELSE
          RollBack
          RollBack
          TABLEREVERT(.T.)
          ………..
        ENDIF
      ELSE
        ThisForm.RollBack()
        ……..
      ENDIF
        ……..

27 июн 06, 12:01    [2815764]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Что-то ты не договариваешь

create cursor test (id i)

INSERT INTO test (id) VALUES (1)

SET DELETED  OFF 
SET MULTILOCKS ON 

CURSORSETPROP("Buffering" ,5)

BEGIN TRANSACTION 

replace id WITH 2

IF TABLEUPDATE(.f.,.t.)
	BEGIN TRANSACTION 
	DELETE 
	IF TABLEUPDATE(.f.,.t.)
		ROLLBACK 
		ROLLBACK  
	ELSE
		END TRANSACTION 
		END TRANSACTION 
	ENDIF 
ELSE
	ROLLBACK tran 
ENDIF 

BROWSE 
27 июн 06, 12:33    [2815981]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
Hi PaulWist ты повторил мой первый вариант :) но он мне не нравится мне и мой последний вариант не нравится так как при падении delete внутри транзакции иногда вылетает ошибка "нельзя делать внутри транзакции..."

Я бы хотел replace и delete сделать и выполнить всего один TableUpdate

Что никак?
27 июн 06, 13:09    [2816223]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
SET DELETED ON
27 июн 06, 13:12    [2816247]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Тогда напиши внятно, что хочешь получить, если вложенные транзакции не нравятся.

Если просто записать мусор и удалить, то

begin tran
replace ....
delete ....

if tableupdate()
end ...
else
rollback 
end
А то, что у тебя ругается - это скорее на tablerevert, что действительно нельзя делать внутри транзакции.
27 июн 06, 13:23    [2816336]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
Дело вовсе на в трпнзакциях у меня какой-то косяк во View

пишу в command

replace num1 with "TT"
Delete

все нормально

TAbleupdate(.T.)

REQUERY()

и у меня поле num1 возвращает значение до replace в чем дело?
27 июн 06, 14:50    [2816900]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
Работает только в случае как я и говорил сначала

REplace

TAbleupdate(.T.)

delete

TAbleupdate(.T.)

REquery()

тогда все нормально
27 июн 06, 14:59    [2816954]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Sea.s2
Дело вовсе на в трпнзакциях у меня какой-то косяк во View

пишу в command

replace num1 with "TT"
Delete

все нормально

TAbleupdate(.T.)

REQUERY()

и у меня поле num1 возвращает значение до replace в чем дело?


Посмотреть, что возвращает Tableupdate() и если .F., то вызвать ф-ию AERROR() и посмотреть на расшифровку ошибки, что-то типа

if not tableupdate()
aerror(arr)
for i = 1 to alen(arr)
?arr(i)
endfor
endif 
27 июн 06, 15:25    [2817133]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
TAbleUpdate везде возвращает .T.

Просто заменяет replace на oldval


replace
delete
tableupdate(.T.)
BROWSE
показывает все нормально

REQUERY()

Замещает на старое
27 июн 06, 15:29    [2817158]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Кстати вот этот lcAlias - это алиас чего, таблицы или view, и какая буферизация стоит на таблице?

Если схема такая, то надо

cursorsetprop('buffering',5,'MyTable')
cursorsetprop('buffering',5,'MyView)

replace..
delete...

tableupdate('MyView')
tableupdate('MyTable')
27 июн 06, 15:29    [2817162]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
Исходная таблица buffering 1
Разве надо буфферизовать исходные таблицы?, никогда итого неделаю

НА View 5
27 июн 06, 15:36    [2817216]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
Тем более TableUpdate(.T.)
я делал два раза на View исходной вообще не трогал
27 июн 06, 15:37    [2817225]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Да, смотри-ка, какая особенность обновления view, действительно новое значение игнорируется, а выставляется только пометка на удаление. Даже затрудняюсь сказать глюк это или так и должно быть, совершенно разное поведение для таблицы и view.
27 июн 06, 16:01    [2817385]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
Так и не смог ито побороть одним TableUpdatom
+ еще одна странность:
Имеется 2 формы с Private DataSession в первой создал структурный индекс
INDEX on expr TAG TT

Захожу в другую где делаю USE того же view in 0

Создаю другой структурный индекс INDEX on expr TAG TT1
выхожу из нее делаю USE in ..

Опять в первой форме создаю индекс INDEX on expr TAG TT
Но теперь создается неструктурный индекс хотя таже DS
и теперь при удалении возникает ошибка закройте неструктурный индекс
Хотя нигде TAG OF не использовал в чем дело?
28 июн 06, 12:43    [2820769]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
Даже вот так
До REQUERY()
можно насоздавать хоть сколько структурных индексов после пойдут неструктурные
CURSORSETPROP("Buffering",3)
INDEX ON num1 TAG num1
CURSORSETPROP("Buffering",5)
REQUERY()
CURSORSETPROP("Buffering",3)
INDEX ON num1 TAG num2
CURSORSETPROP("Buffering",5)
28 июн 06, 13:20    [2820945]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Igor Korolyov
Member

Откуда: Гомель, Беларусь
Сообщений: 2512

Hi Sea!

Поищи тут объяснения способов работы обновляемых представлений - тогда тебе
станет понятно, почему не происходит никакой "замены" при удалении записей.
Попросту нет такой SQL команды "заменить и удалить" - а из двух этих
альтернатив фокс при сбросе буфера представления естественно выбирает более
правильную - удаление.
Также поищи обсуждение индексов по представлениям - это тоже было - да,
после REQUERY() изменяется имя "подлежащего" dbf-а (точнее tmp) - и все
вновь создаваемые индексы идут в "новый" cdx (одноименный новому tmp) - тем
не менее "старый" cdx всё ещё существует и именно он остаётся структурным
cdx-ом.

Posted via ActualForum NNTP Server 1.3

29 июн 06, 02:11    [2823574]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Igor Korolyov

Igor Korolyov
Попросту нет такой SQL команды "заменить и удалить" - а из двух этих
альтернатив фокс при сбросе буфера представления естественно выбирает более
правильную - удаление.


Игорь, ты не прав, если бы такое поведение было как для буфф. таблицы так и для View, то такое предположение можно было бы принять, НО поведение для таблицы отличается от View.

Для буфф. таблицы сбрасываются как изменения поля, так и пометка на удаление, а для View сбрасывается только пометка на удаление.

Налицо, либо баг, либо недокументированная фича.
29 июн 06, 09:03    [2823830]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
Нет. Это не глюк. Все как положено.

View - это НЕ исходная таблица. Это еще одна ДРУГАЯ таблица.

Чтобы изменения, сделанные во View попали в исходную таблицу, необходимо сделать ЗАПИСЬ в исходной таблице. По косвенным признакам, это делается через команды INSERT-SQL, UPDATE-SQL и DELETE-SQL.

Т.е. по команде TableUpdate() выполняется одна из этих 3 команд применительно к текущей записи View.

Но именно, что "одна из", а не несколько. А по постановке задачи Sea.s2 хочет, чтобы было дано несколько команд. Local View на это не рассчитан. В данном случае, придется делать 2 сброса буфера:

REPLACE ...
TableUpdate()
DELETE
TableUpdate()

На первый TableUpdate() пройдет обновление по команде UPDATE-SQL, а на второй TableUpdate() пройдет удаление записи по команде DELETE-SQL. Что, собственно, он и сделал.
29 июн 06, 11:44    [2824715]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
ВладимирМ

ВладимирМ
View - это НЕ исходная таблица. Это еще одна ДРУГАЯ таблица.


Ну дык.

ВладимирМ
Чтобы изменения, сделанные во View попали в исходную таблицу, необходимо сделать ЗАПИСЬ в исходной таблице. По косвенным признакам, это делается через команды INSERT-SQL, UPDATE-SQL и DELETE-SQL.


Владимир, это всё правильно, только при сбросе буфера таблицы почему-то выполняются (по твоей классификации) ДВЕ команды (UPDATE and DELETE), а при сбросе из VIEW только ОДНА (DELETE), те явное нарушение описанной логики.

ВладимирМ
Т.е. по команде TableUpdate() выполняется одна из этих 3 команд применительно к текущей записи View.


Ткни носом в хелп где об этом написано. Пока вижу

автор
Commits changes made to a buffered row, a buffered table, cursor, or cursor adapter.


ВладимирМ
Но именно, что "одна из", а не несколько.


Здесь можно только строить предположения о приоритетах, какая команда выполняется сначала, ведь сброс буфера скорее всего основан на GETFLDSTATE()
29 июн 06, 12:57    [2825200]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
PaulWist
ВладимирМ
Чтобы изменения, сделанные во View попали в исходную таблицу, необходимо сделать ЗАПИСЬ в исходной таблице. По косвенным признакам, это делается через команды INSERT-SQL, UPDATE-SQL и DELETE-SQL.


Владимир, это всё правильно, только при сбросе буфера таблицы почему-то выполняются (по твоей классификации) ДВЕ команды (UPDATE and DELETE), а при сбросе из VIEW только ОДНА (DELETE), те явное нарушение описанной логики.

Почему ты решил, что буфер - это тоже таблица? Или о каком буфере идет речь?

Чтение данных идет по цепочке

Исходная таблица - Local View

Запись данных идет по цепочке

Буфер Local View - Local View - буфер исходной таблицы - исходная таблица

Перенос информации из буфера в исходную таблицу осуществляется каким-то другими механизмами.

То, что описал я - это перенос данных между таблицами. А что такое буфер - не в курсе. Какой механизм сброса буфера - понятия не имею.

PaulWist

ВладимирМ
Т.е. по команде TableUpdate() выполняется одна из этих 3 команд применительно к текущей записи View.


Ткни носом в хелп где об этом написано. Пока вижу

автор
Commits changes made to a buffered row, a buffered table, cursor, or cursor adapter.

Ты путаешь понятия. Я описал перенос данных не из буфера, а между двумя таблицами, поскольку Local View - это однозначно таблица. Вот я и описал перенос данных из одной таблицы в другую. Из Local View в исходную таблицу.

Косвенных ссылок на то, что этот сброс осуществояется SQL-командами в HELP - полно. Но я не знаю ни одной SQL команды, которая одновременно выполняла бы 2 действия - модификацию и удаление.

PaulWist

ВладимирМ
Но именно, что "одна из", а не несколько.


Здесь можно только строить предположения о приоритетах, какая команда выполняется сначала, ведь сброс буфера скорее всего основан на GETFLDSTATE()

Опять. Речь не о буфере, а о взаимодействии таблиц.

Тут команда TableUpdate() вводит в заблуждение, поскольку применительно к Local View она выполняет 2 действия: сбрасывает собственно буфер Local View в сам Local View (тут все в порядке), а затем переносит изменения сделанные в Local View в исходную таблицу. И вот на этом этапе и срабатывают все те механизмы команд SQL о которых я написал выше.
29 июн 06, 13:14    [2825319]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
ВладимирМ

Что бы нам не спорить о понятиях, выполни тест и прокоментируй.

CLOSE DATA ALL

CREATE DATABASE 'LOCALVIEWDB.DBC'

CREATE TABLE 'TABLEFORVIEW.DBF' NAME 'TABLEFORVIEW' (ID I NOT NULL, ;
                           NAME C(10) NOT NULL)

CREATE SQL VIEW "LOCALVIEW" ; 
   AS SELECT Tableforview.id, Tableforview.name FROM localview!tableforview

DBSetProp('LOCALVIEW', 'View', 'UpdateType', 1)
DBSetProp('LOCALVIEW', 'View', 'WhereType', 3)
DBSetProp('LOCALVIEW', 'View', 'FetchMemo', .T.)
DBSetProp('LOCALVIEW', 'View', 'SendUpdates', .T.)
DBSetProp('LOCALVIEW', 'View', 'UseMemoSize', 255)
DBSetProp('LOCALVIEW', 'View', 'FetchSize', 100)
DBSetProp('LOCALVIEW', 'View', 'MaxRecords', -1)
DBSetProp('LOCALVIEW', 'View', 'Tables', 'localview!tableforview')
DBSetProp('LOCALVIEW', 'View', 'Prepared', .F.)
DBSetProp('LOCALVIEW', 'View', 'CompareMemo', .T.)
DBSetProp('LOCALVIEW', 'View', 'FetchAsNeeded', .F.)
DBSetProp('LOCALVIEW', 'View', 'FetchSize', 100)
DBSetProp('LOCALVIEW', 'View', 'Comment', "")
DBSetProp('LOCALVIEW', 'View', 'BatchUpdateCount', 1)
DBSetProp('LOCALVIEW', 'View', 'ShareConnection', .T.)

DBSetProp('LOCALVIEW.id', 'Field', 'KeyField', .T.)
DBSetProp('LOCALVIEW.id', 'Field', 'Updatable', .F.)
DBSetProp('LOCALVIEW.id', 'Field', 'UpdateName', 'localview!tableforview.id')
DBSetProp('LOCALVIEW.id', 'Field', 'DataType', "I")

DBSetProp('LOCALVIEW.name', 'Field', 'KeyField', .F.)
DBSetProp('LOCALVIEW.name', 'Field', 'Updatable', .T.)
DBSetProp('LOCALVIEW.name', 'Field', 'UpdateName', 'localview!tableforview.name')
DBSetProp('LOCALVIEW.name', 'Field', 'DataType', "C(10)")
*
**********************************************
* заполним табличку
USE TABLEFORVIEW IN 0
INSERT INTO TABLEFORVIEW (id, name ) VALUES (1, 'One')
INSERT INTO TABLEFORVIEW (id, name ) VALUES (2, 'Two')
INSERT INTO TABLEFORVIEW (id, name ) VALUES (3, 'Three')
* пехали
SET MULTILOCKS ON 
SET DELETED OFF 
*
* поставим буфферизацию на табличку
CURSORSETPROP("Buffering" ,5,'TABLEFORVIEW')
*
* изменим первую запись в таблице
GO TOP IN TABLEFORVIEW
replace name WITH 'OneOne' IN TABLEFORVIEW
* и удалим её
DELETE IN TABLEFORVIEW
* запишем
?TABLEUPDATE(.t.,.t.,'TableForView')
* закроем и откроем табличку
USE IN TABLEFORVIEW
USE TABLEFORVIEW IN 0 && табличка не буфферизирована
* смотрим - видим измененную и удаленную запись
BROWSE 

*
* делаем тоже самое со View
USE LOCALVIEWDB!LocalVIEW IN 0
* идем на вторую запись
GO 2 IN LocalView
replace name WITH 'TwoTwo' IN LocalVIEW
* и удалим её
DELETE IN LocalVIEW
* записываем
?TABLEUPDATE(.t.,.t.,'LocalView')
* смотрим View - всё замечательно есть изменение, есть удаление
SELECT LocalView 
BROWSE 
* смотрим табличку - а тут прилипла только пометка на удаление
SELECT TABLEFORVIEW
BROWSE 
29 июн 06, 13:58    [2825675]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
ВладимирМ
Member

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

1) "Голая таблица"

Работаем только с буфером таблицы. Все изменения по команде TableUpdate() переносятся из буфера в исходную таблицу. Причем сначала переносится метка на удаление и только потом модификация.

Как я это узнал. Поставил в триггерах таблицы .F. после того, как TableUpdate() вернул .F. посмотрел значение 5 элемента массива полученного по AERROR(). Там стояла 3. Т.е. сработал триггер на удаление.

2) Local View

По команде TableUpdate() происходит 2 события:

-) Сброс буфера Local View в собственно Local View
-) Перенос изменений сделанных в Local View в исходную таблицу. Заметь, здесь речь уже вообще не идет о буферах. Это просто обновление данных в одной таблице данными из другой.

Хотя порядок этих двух операций скорее всего обратный: сначала перенос из буфера Local View в исходную таблицу, а потом сброс буфера самого Local View.

Перед переносом вполне логично делается анализ на тип выполняемого изменения. Сначала делается анализ на факт удаления. Имеет место быть. Вот и выполняем удаление.

А вот следующего шага на модификацию уже удаленной записи не делается, что вполне логично. Какой смысл изменять не существующую запись?

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

Попробуй в созданном Local View создать новую запись и тут же ее удалить. При сбросе буфера в исходной таблице новой удаленной записи не появится. Однако если то же самое сделать на самой таблице, то новая удаленная запись появится.

Разные механизмы работают при "простом" сбросе буфера и при переносе изменений из Local View в таблицу источник.
29 июн 06, 19:39    [2827899]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
ВладимирМ
Комментирую

1) "Голая таблица"

Работаем только с буфером таблицы. Все изменения по команде TableUpdate() переносятся из буфера в исходную таблицу. Причем сначала переносится метка на удаление и только потом модификация.



Ну, что же, ты подтвердил мои предыдущие слова

PaulWist
Для буфф. таблицы сбрасываются как изменения поля, так и пометка на удаление, а для View сбрасывается только пометка на удаление.


ВладимирМ
2) Local View
.......
Перед переносом вполне логично делается анализ на тип выполняемого изменения. Сначала делается анализ на факт удаления. Имеет место быть. Вот и выполняем удаление.

А вот следующего шага на модификацию уже удаленной записи не делается, что вполне логично. Какой смысл изменять не существующую запись?


Вот это-то и удивило автора топика, для таблицы делаем replace-delete, получаем все изменения в таблице, он ожидал такого же поведения и для View, ан нет "облом-с".

Поэтому было написано

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


Ну и твоё заключение

ВладимирМр
Разные механизмы работают при "простом" сбросе буфера и при переносе изменений из Local View в таблицу источник.
30 июн 06, 11:05    [2829405]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
Что-то не получается переоткрыть структурный индекс и уничтожить неструктурный перед удалением

LOCAL lcIdx

  CURSORSETPROP("Buffering", 3, ThisForm.Alias)
  m.lcIdx   = SET("Index")
  m.lcIdx   = SUBSTR(lcIdx, 1, AT(".cdx", lcIdx) + 3)
  MESSAGEBOX(SET("Index"))
  CLOSE INDEXES
  &&SET INDEX TO
  SET INDEX TO &lcIdx
  SET ORDER TO
CURSORSETPROP("Buffering", 5, ThisForm.Alias)

REQUERY()


После requery()
неструктурного индекса нет структурный виден на диске но
set index устанавливает связь на индекс исходной таблицы а стуктурный индекс view не видит
30 июн 06, 12:34    [2830102]     Ответить | Цитировать Сообщить модератору
 Re: Replace, Delete in Transaction  [new]
Sea.s2
Guest
Вот это что за бред выполняю код без DELETE все проходит без ошибки

С DELETE проподает структурный индекс view и связь уходит на индекс исходной таблицы и соответсвенно вылетает ошибка TAG индекса не найден
у меня уже голова идет кругом от итих заморочек ну в чем тут дело
LOCAL lcIdx, lcOrder, lcDesc
  CURSORSETPROP("Buffering", 3, ThisForm.Alias)
    m.lcOrder = ORDER(ThisForm.Alias)
    m.lcIdx   = SET("Index")
    m.lcIdx   = SUBSTR(lcIdx, 1, AT(".cdx", lcIdx) + 3)
    SET INDEX TO &lcidx
    IF !EMPTY(lcOrder) THEN
      SET ORDER TO TAG (lcOrder) ASCE
    ENDIF
  CURSORSETPROP("Buffering", 5, ThisForm.Alias)
  
        BEGIN TRANSACTION  
       DELETE  &&Если убрать то все будет нормально
      TABLEUPDATE(.F., .T., ThisForm.Alias)
       ROLLBACK
3 июл 06, 08:22    [2834898]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / FoxPro, Visual FoxPro Ответить