Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Прошу помощи для старой версии FP / 10 сообщений из 10, страница 1 из 1
10.09.2006, 15:57
    #33976470
mikle_new
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
Есть две таблицы. В которых есть разное количество записей. Необходимо в большую таблицу внести изменнение в поле при условии совпадени полей во второй таблице. Пытаюсь сделать что-то типа:
UPDATE dsber set dsber.Account = trans.Nomer1 where dsber.Name=trans.Name1 and dsber.Name1=trans.Name2 and dsber.Name2=trans.Name3
пишет, что обновляет только 1 запись
Если делать
select * from dsber a, trans b where a.Name=b.Name1 and a.Name1=b.Name2 and a.Name2=b.Name3
Выводит 794 записи.
Как обновить все записи, который выдает Select?
VP - 5.0
...
Рейтинг: 0 / 0
10.09.2006, 18:46
    #33976601
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
Команда Update-SQL "научилась" использовать подзапросы только в VFP9.

Для младших версий FoxPro приведенный тобой синтаксис означает, что замена будет произведена только среди тех записей таблицы dsber для которых выполняется условие WHERE в отношении текущей записи таблицы trans . Нет перемещения по таблице trans

Решений проблемы несколько:

-) Использовать старую команду UPDATE (не путать с Update-SQL), оставленную для совместимости. Но, поскольку ее явно не рекомендуют использовать, то "мы пойдем другим путем"

-) "Тупое" сканирование записей

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT trans
SET ORDER TO  0   && для оптимизации (ускорения) команды LOCATE
SELECT dsber 
SET ORDER TO  0   && для оптимизации (ускорения) команды SCAN
SCAN
	SELECT trans
	LOCATE FOR trans.Name1=dsber.Name and ;
		trans.Name2=dsber.Name2 and ;
		trans.Name3=dsber.Name3

	SELECT dsber 
	IF FOUND("trans")
		REPLACE Account WITH trans.Nomer1 
	ENDIF
ENSCAN

Ускорение команды LOCATE будет в случае наличия простых индексов по полям trans.Name1, trans.Name2 и trans.Name3. Или хотя бы по одному из них, но обладающего наибольшей селективностью (меньший процент повторяющихся значений)

-) Если общая длина полей trans.Name1+trans.Name2+trans.Name3 не превышает 120 символов (при настройке SET COLLATE TO MACHINE - это настройка по умолчанию - до 240 символов), то можно построить простой индекс

Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT trans
INDEX ON Name1+Name2+Name3 TO TempIndex.idx COMPACT
SELECT dsber 
SET ORDER TO  0   && для оптимизации (ускорения) команды REPLACE 
REPLACE FOR SEEK(dsber.Name+dsber.Name2+dsber.Name3,"trans","TempIndex") ;
	Account WITH trans.Nomer1

Правда, для разовой модификации это смысла не имеет, поскольку время построения индекса будет сопоставимо со временем сканирования таблиц по предыдущему варианту.
...
Рейтинг: 0 / 0
10.09.2006, 19:18
    #33976630
mikle_new
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
Спасибо за быстрый ответ.
Действительно преобразование необходимо выполнить 1 раз.
Запустил Ваш код, однако выдается ошибка:
Nesting error (Error 96)

One of these situations has been encountered:

· A DO is present without a matching ENDDO or vice versa
· A SCAN is present without a matching ENDSCAN or vice versa
· A FOR is present without a matching ENDFOR or vice versa
· A LOOP or EXIT clause is present outside the DO WHILE ... ENDDO, FOR ... ENDFOR, or SCAN ... ENDSCAN commands.

Видимо не закрыт FOR? Но не могу понять где он должен быть закрыт.
Прошу прощения за свою бестолковость - раньше с FoxPro не сталкивался.
...
Рейтинг: 0 / 0
10.09.2006, 19:29
    #33976635
mikle_new
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
Да, опечатку в Вашем коде (ENDSCAN) я подправил, но это не помогло. ;o(
...
Рейтинг: 0 / 0
10.09.2006, 20:23
    #33976694
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
mikle_newДа, опечатку в Вашем коде (ENDSCAN) я подправил, но это не помогло. ;o(
Почему не помогло? Ошибка 96 именно с этим и связана. Есть открывающая команда, но нет закрывающей.

Возможно, ты еще что не так записал в команде LOCATE FOR.

Для FoxPro символ точки с запятой ";" - это символ переноса команды. Т.е. сигнал о том, что команда продолжается на следующей строке.

На этапе компиляции никакого сообщения об ошибке не возникает? Если возникает, то на какой строке?
...
Рейтинг: 0 / 0
10.09.2006, 20:26
    #33976699
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
У тебя неудачное название таблицы "trans". Совпадает с ключевым словом FoxPro "TRANSFORM". В принципе, на работу это влиять не должно, но... Попробуй изменить алиас таблицы при открытии

Код: plaintext
USE Trans.dbf IN  0  ALIAS MyTrans

Соответственно, внеси исправления в код программы.
...
Рейтинг: 0 / 0
10.09.2006, 20:35
    #33976707
mikle_new
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
Почитал Help, понял, что нужно Ваш код оформить через программку. Написал программу:
SET DEFAULT TO "c:\program files\work"
USE "c:\program files\work\trans.dbf"
USE "c:\program files\work\dsber.dbf" in 0
SELECT trans
SET ORDER TO 0
SELECT dsber
SET ORDER TO 0
SCAN
SELECT trans
LOCATE FOR trans.Name1=dsber.Name and ;
trans.Name2=dsber.Name1 and ;
trans.Name3=dsber.Name2
SELECT dsber
IF FOUND("trans")
REPLACE Account WITH trans.Nomer1
ENDIF
ENDSCAN
Однако при выполнении в точку где Replace программа не попадает. В чем может быть дело?
...
Рейтинг: 0 / 0
10.09.2006, 20:44
    #33976714
mikle_new
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
Подправил Alias и код. Ошибок при компиляции не выдает. Однако на строку с Replase не попадает. Интересно, что после выполнение Locate в переменной MyTrans.Name по дебагеру видно только пустое значение. може быть проблема в услоавиях для Loсate?
...
Рейтинг: 0 / 0
10.09.2006, 20:56
    #33976723
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
У тебя поля, которые ты сравниваешь имеют одинаковую длину? Размерность полей какая?

Дело в том, что логика сравнения символьных полей в команде Select-SQL несколько отличается от логики сравнения символьных полей в "обычных" командах. Как правило, это проявляется именно в случае сравнения полей разной длинны. Подробнее читай описание настроек SET EXACT (для обычных команд) и SET ANSI (для Select-SQL)

Ну, например, если поле trans.Name1 имеет размерность C(20), а поле dsber.Name имеет размерность C(25), то сравнение

trans.Name1 = dsber.Name

в случае, если содержимое отличается только концевыми пробелами при настройках по умолчанию, в команде Select-SQL вернет .T., а в обычных командах .F.

Измени команду LOCATE следующим образом:

Код: plaintext
1.
2.
3.
LOCATE FOR trans.Name1=RTRIM(dsber.Name) and ;
	trans.Name2=RTRIM(dsber.Name2) and ;
	trans.Name3=RTRIM(dsber.Name3)

В таком синтаксисе размерность полей не должна влиять на результат.

То, что после команды LOCATE в таблице Trans содержимое полей пустое, означает, что поиск прошел неудачно и указатель записи встал в положение EOF()=.T. Т.е. встал на некую фиктивную запись, все поля которой имеют пустое значениею
...
Рейтинг: 0 / 0
10.09.2006, 21:08
    #33976730
mikle_new
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи для старой версии FP
Действительно именно в этом была проблема. Большое спасибо за реальную помощь.
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Прошу помощи для старой версии FP / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]