powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Определение нахождения в курсоре
25 сообщений из 28, страница 1 из 2
Определение нахождения в курсоре
    #33501431
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть курсор, в него добавляются записи, там же редактируются, после чего переносяться в основную таблицу, на основе которой он был сделан. При этом срабатывает триггер, который регистрирует эти действия. Вопрос в том, как внутри триггера определить, что вызвал его курсор, а не таблица прородитель.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501495
Фотография Владимир СА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Prot0sЕсть курсор, в него добавляются записи, там же редактируются, после чего переносяться в основную таблицу, на основе которой он был сделан. При этом срабатывает триггер, который регистрирует эти действия. Вопрос в том, как внутри триггера определить, что вызвал его курсор, а не таблица прородитель.Для этого служат как Local View баз параметров, так и параметризированные Local View. Или что-то я непонял???
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501524
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Суть в том, что уже есть готовая БД с клиентским приложением, необходимо было добавить простую регистрацию событий, что я и сделал с помощью триггеров. Но получилось, что при редактировании курсора события тоже записываются, а это мне не нужно, мне необходимо только окончательное действие произведенное на основной таблице. И менять я могу только код триггера, отсюда и вопрос, как определить откуда был вызван триггер, т.е. вызван ли он из курсора, и если да, то ничего не записывать в журнал.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501554
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот часть кода

* создали курсор

SELECT plan_p
=AFIELDS(la_plan_str)
CREATE CURSOR cur_plan_p FROM ARRAY la_plan_str

* какие-то манипуляции с его данными

* перенос в основную таблицу
SELECT cur_plan_p

SCAN
SCATTER TO la_tek
SELECT plan_p
APPEND BLANK
GATHER FROM la_tek
SELECT cur_plan_p
ENDSCAN

* удаление записей
SELECT cur_plan_p
DELETE ALL
GO TOP

Так вот в журнал записывается вот это самое удаление, спрашивается зачем оно мне, когда, если рассуждать логически, на самом деле я ее добавил в БД.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501580
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Триггер выполняется всегда, если произведено действие модификации данных,
и не важно каким образом запись попала в таблицу (прямой INSERT или ввод ручками).

Приведите пример кода, когда модификация в курсоре приводит к срабатыванию триггера в какой-то таблице.

У меня есть сильное подозрение, что

1. Ваша таблица имеет Buffering = 3
2. Процесс модификации таблицы не обёрнут в транзакцию
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501588
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вообще ерунда какая-то, ничего не понимаю, сейчас все заработало. ???? Т.е. в курсоре не срабатывает этот триггер.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501605
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А теперь опять эта хрень появилась 8(((((((((((
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501642
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По поводу транзакции правда, что не обернут. Но тут ведь вот что, последнее действие почему-то классифицируется как удаление записи. Почему не понятно???
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501736
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приведите пример
1. создания БД
2. создания таблицы
3. создания триггера
4. собственно модификации, где проявляется проблема (думаю в тестовом примере Вы не получите такого результата, скорее всего ищите ошибку в своём коде)
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501912
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот тестовый пример

SELECT mytable
=AFIELDS(la_plan_str)
CREATE CURSOR cur_mytable FROM ARRAY la_plan_str


SELECT cur_mytable
INSERT INTO cur_mytable (id, name) VALUE(0,"???")


SELECT cur_mytable

SCAN
SCATTER TO la_tek
SELECT mytable
APPEND BLANK
GATHER FROM la_tek
SELECT cur_mytable
ENDSCAN

SELECT cur_mytable
DELETE ALL
GO TOP

При этом в таблице mytable запись остается, а в журнал записываются следующие строки

mytable A
mytable A
mytable M
mytable D

А должна быть только mytable A
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33501990
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А текст триггера как бы увидеть.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502063
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот собственно, только для теста правда, но от этого суть не меняется

PROC TRG(c_TblName, c_Act)
INSERT INTO tjournal (tbl,act);
VALUES (c_TblName, c_Act)
RETURN .T.


Вставляется в поле триггеров таблицы mytable в виде trg("mytable","A"), trg("mytable","M"), trg("mytable","D") соответственно.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502231
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Триггер НЕ МОЖЕТ сам по себе сработать на действия в ДРУГОЙ таблице. Он привязан только и исключительно к одной (конкретной) таблице. А курсор - это как раз и есть ДРУГАЯ таблица никакого отношения к исходной не имеющая.

Пройдитесь в вашем тестовом примере отладчиком по шагам и посмотрите на какой команде происходит вызов триггера.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502258
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запусти скрипт и попробуй добиться своего результата

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
* создаем БД
CREATE DATABASE TestTrigger
* создаеи табличку
CREATE TABLE TestTrigger (ID i)
* создаем лог табличку
CREATE TABLE LogTrigger (Action c( 1 ))
* закрываем таблички
USE IN TestTrigger
USE IN LogTrigger
* создаем ф-ии для триггеров
STRTOFILE([FUNCTION InsertTrigger ] + CHR( 13 ) + CHR( 10 ) + ;
	[INSERT INTO LogTrigger (Action) VALUES ('I') ] + CHR( 13 ) + CHR( 10 ) + ;
[ENDFUNC  ] + CHR( 13 ) + CHR( 10 ) + ;
[FUNCTION UpdateTrigger ] + CHR( 13 ) + CHR( 10 ) + ;
[	INSERT INTO LogTrigger (Action) VALUES ('U') ] + CHR( 13 ) + CHR( 10 ) + ;
[ENDFUNC  ] + CHR( 13 ) + CHR( 10 ) + ;
[FUNCTION DeleteTrigger  ] + CHR( 13 ) + CHR( 10 ) + ;
[	INSERT INTO LogTrigger (Action) VALUES ('D') ] + CHR( 13 ) + CHR( 10 ) + ;
[ENDFUNC], 'Func.prg')
* добавляем ф-ии как ХП БД
APPEND PROCEDURES FROM 'Func.prg'
* привязываем триггеры для таблички
CREATE TRIGGER ON TestTrigger FOR INSERT as InsertTrigger()
CREATE TRIGGER ON TestTrigger FOR UPDATE as UpdateTrigger()
CREATE TRIGGER ON TestTrigger FOR DELETE as DeleteTrigger()
* компилируем ХП
COMPILE DATABASE TestTrigger 
* создаем просто курсор
CREATE CURSOR test (ID i )
* добавляем в него запись
INSERT INTO Test (ID) VALUES ( 1 )
* добавляем из курсора запись в таблицу
INSERT INTO TestTrigger (ID) SELECT ID FROM Test
* удаляем из курсора данные
DELETE FROM test
* всё смотри, что получилось
SELECT LogTrigger 
BROWSE 
* видим, что запись имеет 'I'
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502283
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ошибку я уже нашел, если я не ошибаюсь, то это из-за того что курсор создается вот так

SELECT plan_p
=AFIELDS(la_plan_str)
CREATE CURSOR cur_plan_p FROM ARRAY la_plan_str

таким образом он получает в наследство триггеры, что не есть хорошо. Хочется повторить, что код проги менять нельзя, нужно сделать как-то изнутри тела триггера.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502301
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PaulWistЗапусти скрипт и попробуй добиться своего результата

8)

Конечно, я таким образом ничего не добьюсь, но думаю если создать триггер вот так

Код: plaintext
1.
2.
3.
SELECT TestTrigger
=AFIELDS(la_arr_str)
CREATE CURSOR test FROM ARRAY la_arr_str

то записи в журнале будут уже другие.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502314
alex11100
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
переберите массив la_arr_str
и подправьте значения
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502337
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мда, действительно, про это я забыл

AFIELDS помещает в элементы

автор13
Insert trigger expression
Character

14
Update trigger expression
Character

15
Delete trigger expression
Character

Ну что же надо их очистить, таким образом отвяжем курсор от триггеров

Мда ...., век живи век учись.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502349
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Первой командой в теле триггера напишите примерно следующее

Код: plaintext
1.
2.
3.
IF JUSTEXT(DBF()) = "TMP"
	RETURN
ENDIF

Дело в том, что курсоры - это временные таблицы, которые имеют имя вроде

1234567890.TMP

Функция DBF() читает имя файла в текущей рабочей области. А триггер автоматически переключается в рабочую область таблицы, вызвавшей его срабатывание.

Вот первой командой и проверь расширение той таблицы, которая вызвала срабатывание триггера.

Хотя, конечно, требование странное. Программу менять нельзя, а базу данных можно. Обычно наоборот, стремяться изо всех сил сохранить именно базу данных.

Кстати, создать курсор как копию исходной таблицы можно так:

Код: plaintext
SELECT * FROM MyTab INTO cur_plan_p READWRITE WHERE .F.

Опция READWRITE появилась только в VFP7. Для младших версий, чтобы сделать курсор редактируемым его надо переоткрыть.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502406
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Небольшой коментарий к

Код: plaintext
1.
2.
IF JUSTEXT(DBF()) = "TMP"
	RETURN
ENDIF

что бы уж совсем отвязаться расширения файла

Код: plaintext
1.
2.
IF !FILE(alias())
RETURN
ENDIF 

те для фокса курсор не ассоциируется с файлом ОС, хотя TEMP файл всё равно создаётся (при определенных условиях).
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502500
Prot0s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По поводу
Код: plaintext
1.
2.
3.
   IF (JUSTEXT(DBF()) = "TMP")
      RETURN .T.
   ENDIF
все понятно, а вот зачем
Код: plaintext
1.
2.
3.
   IF FILE(alias())
      RETURN .T.
   ENDIF
хотя и без него работает, спасибо.

Но еще одна пробла возникла. В одном курсоре идет дубликация строки по кнопке с помощью следующего кода
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT cur_mytable
IF BOF() .OR. EOF()
   RETURN
ENDIF
	
SCATTER TO la_tek
INSERT BLANK
GATHER FROM la_tek

REPLACE id WITH  999 
И выдается ошибка INSERT cannot be issuied ... Как я понял это из-за того, что INSERT старая команда. Просто если вставить APPEND то все на ура, хотя делают одно и тоже. Может кто-нибудь пояснить в чем проблема.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502521
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВставляет в текущую таблицу новую запись. Данная команда включена для совместимости с предыдущими версиями. Пользуйтесь вместо нее командами APPEND или INSERT - SQL.

Синтаксис

INSERT [BEFORE] [BLANK]

Параметры

BEFORE

Вставляет новую запись в текущую таблицу непосредственно перед текущей записью. После этого новая запись отображается для редактирования. Можно добавлять новые записи из окна редактирования.

BLANK

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

Комментарии

Если команда INSERT выдана без предложений BEFORE и BLANK, новая запись добавляется, а затем отображается для редактирования. Новые записи можно добавлять из окна редактирования.
В Visual FoxPro командой INSERT нельзя пользоваться в таблице базы данных, для которой включена буферизация таблицы или буферизация строк, а также в таблице с правилами ссылочной целостности, такими как триггеры, первичные ключи или ключи-кандидаты и т.д. Подробнее о буферизации таблиц и строк см. CURSORSETPROP( ), а о ссылочной целостности ѕ главу 7 "Работа с таблицами" Руководства разработчика.
Если установка SET CARRY имеет значение ON, в новую запись будут автоматически скопированы данные из текущей записи.

Если файл индексирован, команда INSERT работает как APPEND.

Замечание Командой INSERT не рекомендуется пользоваться в больших таблицах, поскольку вставка записи ближе к началу таблицы будет приводить к переписыванию почти всех записей. На это может уйти очень много времени. Пользуйтесь командой INSERT - SQL.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502556
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWist
Код: plaintext
1.
2.
IF !FILE(alias())
RETURN
ENDIF 

те для фокса курсор не ассоциируется с файлом ОС, хотя TEMP файл всё равно создаётся (при определенных условиях).
Не кажется, что сам себе противоречишь?

TEMP файл может физически быть создан на винте, но может и не быть. Здесь нет никакой гарантии. Т.е. проверка на факт существования файла может и не сработать.

Кроме того, ты зачем-то пытаешься найти ФАЙЛ по имени АЛИАСА. Тут даже реальную таблицу можно не найти:

USE MyTable.dbf ALIAS tab1
?FILE('tab1')

Гарантировано получишь .F.
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502659
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ Не кажется, что сам себе противоречишь?

Владимир, это мы обсуждали здесь http://forum.foxclub.ru/read.php?29,153967,153967#msg-153967

ВладимирМTEMP файл может физически быть создан на винте, но может и не быть. Здесь нет никакой гарантии. Т.е. проверка на факт существования файла может и не сработать.

Там же прошли - не зависимо от размера курсора, фокс его не видит как файл.

ВладимирМКроме того, ты зачем-то пытаешься найти ФАЙЛ по имени АЛИАСА. Тут даже реальную таблицу можно не найти:

USE MyTable.dbf ALIAS tab1
?FILE('tab1')

Гарантировано получишь .F.

Да совершенно верно, не правильно искать по алиасу.

Скоро год будет как в класс закатал, забыл уже.

Надо

Код: plaintext
1.
2.
3.
4.
CREATE CURSOR test (ID i)

?FILE(CURSORGETPROP("SourceName"))

?FILE(DBF())
...
Рейтинг: 0 / 0
Определение нахождения в курсоре
    #33502823
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWistВладимир, это мы обсуждали здесь http://forum.foxclub.ru/read.php?29,153967,153967#msg-153967
Помнишь, чем там все закончилось?

Между прочим, я проверил.

1) Посмотрел, какой же у меня реальный объем оперативки включая виртаульную память. Оказалось около 1,2 ГБ

2) Создал по твоему тесту (что по ссылке) курсор

3) Посмотрел в проводнике (он там прекрасно виден) что его размер стал больше размера оперативки

После этого

?FILE(DBF()) - вернул .T.

Т.е. использование File() - заведомо сомнительный способ. Хотя, на современных компах объем оперативки уже давно перевалил за 2ГБ (предел для таблиц). Так что, с некоторыми оговорками это можно использовать.
...
Рейтинг: 0 / 0
25 сообщений из 28, страница 1 из 2
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Определение нахождения в курсоре
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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