Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
заметил интересный эффект, такой код: GO TOP IN tmptab DO WHILE !EOF("tmptab") UPDATE tmptab SET id_meter=y WHERE id_meter = x ENDDO эффект такой если _tally от update > 1, то текущая запись в tmptab сдвигается как надо, но если _tally=1, то текущая запись остается той же самой! сделал так: GO TOP IN tmptab DO WHILE !EOF("tmptab") UPDATE tmptab SET id_meter=y WHERE id_meter = x IF _tally<=1 SKIP IN tmptab ENDIF ENDDO все работает, но вообще странно то ли это баг, то ли фича(но если фича то скорее вредная чем полезная) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 15:13 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
эффект действительно интересный а если не мудрить и оставить в покое системную переменную которую лучше не трогать и вместо GO TOP IN tmptab DO WHILE !EOF("tmptab") UPDATE tmptab SET id_meter=y WHERE id_meter = x IF _tally<=1 SKIP IN tmptab ENDIF ENDDO записать replace id_meter with y for id_meter = x in tmptab то что будет? кстати команда апдейт кажеться блочит таблицу а реплас этого не делает ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 15:22 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
leafкстати команда апдейт кажеться блочит таблицу а реплас этого не делает Вообще-то наоборот. REPLACE FOR блокирует всю таблицу, а UPDATE-SQL только изменяемые записи. Хотя сам пример действительно надуманный. Поскольку нигде в HELP не говорится как поведет себя указатель записи при выполнении команды UPDATE-SQL, то это надо контролировать самостоятельно. Ну, а в приведенном случае вообще полный бред получиться в том смысле, что невозможно предсказать результат модификации . Но это уже на совести автора примера. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 15:35 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
replace for вообще не подходит для использования в while, GO TOP IN tmptab DO WHILE !EOF("tmptab") replace id_meter with y for id_meter = x in tmptab enddo после первого же реплэйса выходим из while. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 15:37 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
lesha_spbreplace for вообще не подходит для использования в while Подходит, но при определенных условиях. Просто кроме опции FOR в команде REPLACE есть и опция WHILE. При наличии соответсвующего индекса все можно сделать. Но надо знать конкретную задачу, а не "то, не знаю что", что написано в примере. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 15:45 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
тяжело с гуру спорить но всё же в споре рождаеться истина как говориться Платон мне друг Возможно у меня старая версия хелпа но всё же вот выдержка из хелпа к пятерке : В отличии от команды replace команда update использует блокировку записей при обновлении множества записей в таблице открытой с разделяемым доступом . Это сокращает разрешение конфликтов записей в многопользовательской среде, но также может понизить производительность. Для максимальной производительности открывайте таблицу для монопольного использования или используйте FLOCK( ), что бы блокировать таблицу. На мой взляд весьма красноречиво или я чего не понимаю ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 15:46 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
специально для автора там есть такая маленькая опция for отсюда вопрос нужен ли Вам вообще цикл? Ну если уж так не можете без него жить то нате: select tmptab scan for id_meter = x replace id_meter with y endscan ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 15:49 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
leafВозможно у меня старая версия хелпа но всё же вот выдержка из хелпа к пятерке : В отличии от команды replace команда update использует блокировку записей при обновлении множества записей в таблице открытой с разделяемым доступом . Это сокращает разрешение конфликтов записей в многопользовательской среде, но также может понизить производительность. Для максимальной производительности открывайте таблицу для монопольного использования или используйте FLOCK( ), что бы блокировать таблицу. А где противоречие с тем что я написал? ВладимирМREPLACE FOR блокирует всю таблицу, а UPDATE-SQL только изменяемые записи ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 16:00 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
ну в принципе противоречия нет хотя явного указания на блокировку таблицы я не нашел по крайней мере в своем А проверять руками нет желания остается принять к сведению на веру хотя при случае обязательно проверю возможно блокировка заголовка просто необходима хотя и в этом случае не понятно что лучше блокировка записей по одной записи или единичная блокировка заголовка? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 16:15 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
согласен пример я привел не самый лучший:) на самом деле было так: select * from tab where IsTaken=0 order by id_meter into cursor tmptab readwrite GO TOP IN tmptab DO WHILE !EOF("tmptab") ищем новое значение для tmptab.id_meter; if нашли replace id_meter WITH tMId.idob IN tmptab endif SKIP IN tmptab ENDDO попробовал делать через update, чтобы избавится от лишних итераций в while. (записей с одинаковым id_meter в tmptab обычно несколько) Но с update я был не прав. сделал так: local curid select * from tab where IsTaken=0 order by id_meter into cursor tmptab readwrite GO TOP IN tmptab DO WHILE !EOF("tmptab") curid=tmptab.id_meter ищем новое значение для tmptab.id_meter; if нашли replace id_meter WITH tMId.idob WHILE id_meter=curid IN tmptab else SKIP IN tmptab endif ENDDO В таком варианте все отрабатывает правильно и как понимаю replace while все таки быстрее чем заменять по одной записи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 16:23 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
хотите совет - приведите весь текст полностью ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2005, 17:02 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
щас все работает как надо.но давайте все же приведу мою ситуацию подробней. может я что нибудь делаю не лучшим образом)) суть в следующем: нужно из некоторых таблиц одной базы перенести все новые данные в аналогичные таблицы другой базы. то что данные новые определяет столбец istaken. таблицы реально находятся на sql server работаем с ними через remote view. формат таблиц в общем случае можно описать так: idob id_meter nomer istaken ну и набор других полей при переносе данных из одной базы в другую нужно изменить ссылку id_meter. т.к. она может не совпадать. в итоге имеем: local curid *выбираем все данные из исходной таблицы: myquery = select * from tab where IsTaken=0 order by id_meter SqlExec(source_handle, MyQuery, "tmptab") GO TOP IN tmptab DO WHILE !EOF("tmptab") curid=tmptab.id_meter *ищем в источнике в таблице meters номер объекта по его idob'у USE IN SELECT("tMNum") MyQuery = "select meter_numb from meters where idob = "+tmptab.id_meter SqlExec(source_handle, MyQuery, "tMNum") *ищем в получателе в таблице meters по номеру объекта его idob. это и *будет нужный нам id_meter USE IN SELECT("tMId") MyQuery = "select idob from meters where meter_numb = "+tMNum.meter_numb sqlFlag = RunSqlExec(target_handle, MyQuery, "tMId") IF RECCOUNT("tMId") > 0 &&если нашли replace id_meter WITH tMId.idob WHILE id_meter=curid IN tmptab else SKIP IN tmptab endif ENDDO получили в tmptab новые данные в нужном нам виде, после чего они через remote view помещаются в получатель. например так: SELECT TMPPOW APPEND FROM DBF("tmptab") SELECT TMPPOW TABLEUPDATE() вот и все далее работает некая процедура на sql server но это к делу не относится ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.04.2005, 15:35 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
Hi leaf! Там не совсем хороший текст, вот ты и не понял :) REPLACE ... FOR и REPLACE ... WHILE производят блокировку ВСЕГО файла для своей работы - т.е. они выполняют неявный FLOCK() - что конечно способно привести к конфликту - если в таблице уже есть какая-то блокировка (причём совершенно не имеет значения - попадает заблокированная запись под условие в FOR или WHILE или нет!!!) А вот при SQL UPDATE производится только RLOCK() блокировка, и только для тех записей, которые попадают под условие - т.е. если заблокированы "другие" записи - это ничему не мешает. А проблема с производительностью в том, что действительно быстрее наложить одну FLOCK() и потом спокойно поменять кучу записей, чем возится с блокировкой каждой отдельной изменяемой записи. Однако надо ещё провести тест - я не удивлюсь если разница в скорости будет минимальна... P.S. REPLACE БЕЗ "множественных" диапазонов (т.е. тот который только текущую запись меняет) делает RLOCK() - и это хорошо :) Posted via ActualForum NNTP Server 1.1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.04.2005, 02:56 |
|
||
|
странность в while+update+skip
|
|||
|---|---|---|---|
|
#18+
спасибо игорь примерно так я и понял особых проблем не возникнет как в первом так и во втором случае при грамотном использовании фокспро так что оба способа на мой взляд равноценны но всё же сумничал я не зря этот момент для меня стал более ясен спасибо всем так что всем спасибо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.04.2005, 12:07 |
|
||
|
|

start [/forum/topic.php?fid=41&fpage=324&tid=1594324]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
30ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
43ms |
get tp. blocked users: |
1ms |
| others: | 211ms |
| total: | 325ms |

| 0 / 0 |
