powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / %OnBeforeSave
15 сообщений из 15, страница 1 из 1
%OnBeforeSave
    #34122107
Фотография rodb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
здраствуйте,

научите, что нада написать в методе
%OnBeforeSave класса, чтобы при сохранении изменить какое-нибудь другое
свойство сохраняемого объекта.






Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34122268
Ptn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зависит от версии Каше

в 4.x было достаточно написать
Код: plaintext
1.
2.
3.
4.
5.
6.
Method %OnBeforeSave(ins As %Library.Boolean =  0 ) As %Library.Status
{
 set ..History.SetAt(..DocState, 1 +..History.Previous())
 set ..DocState=$S(..Rest= 0 : 2 ,..Rest'=..Summ: 1 , 1 : 0 )
 quit $$$OK
}
Либо
Код: plaintext
1.
 set i%DocState=$S(i%Rest= 0 : 2 ,i%Rest'=i%Summ: 1 , 1 : 0 )

в 5.x механизм сохранения был измен и теперь это срабатывает только для "простых" полей.
Для встроенных массивов или списков метод начинает срабатывать только если данные поля изменялись перед сохранением - то есть метились как модифицированные. Поэтому строку
Код: plaintext
1.
 set ..History.SetAt(..DocState, 1 +..History.Previous())
приходётся переносить в новый обработчик %OnAddToSaveSet()
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34122349
Фотография rodb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ptn,

скажите, почёму вот так не срабатывает?

Method %OnBeforeSave(ins As %Library.Boolean = 0) As %Library.Status
{
set History = "OK"
//^^^^^^ отсутствуют 2 точки
quit $$$OK
}

пятерка.
причем компилится - без ошибок, но не срабатывает молча.




Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34122356
Фотография rodb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще один ньюанс.

при апдейте со сторный прямого доступа

%OnBeforeSave

срабатывает. А при апдейте со стороны ODBC не срабатывает.
и как с этим бороться? Скрещивать ODBC и прямой доступ?


Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34123314
Ptn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну во первых для доступа к полям или методам объекта двуточечный синтаксис обязателен. Просто обязателен
Код
Код: plaintext
Set History=$$$OK
не является ошибочным.
Вы присаваете значение $$$OK некой локальной переменной History - и компилятор тут совершенно не причем - нужно ПОЛЕ History используете натацию ..History.

На конструкцию i%History у меня не смотрите - это я погорячился по видимо.

Второем растет из идеалогии Каше. Она предоставляет тройственный доступ
прямой - всё делаешь сам
Объектный - сам + базовые классы
SQL - "всё" делаешь через SQL

Проблема в том что обработчики событий %OnXXX (%OnNew,%OnBeforSave,%OnDelete) это все обработчики объектного уровня.

ODBC же это классический доступ посредством SQL. И события там стандартные SQL - то есть триггера.
Которые точно так же нужно определять в классе.
%OnBeforSave в данном случае даже не вызывается.

Как правило "мы" делаем отдельный метод - которые потом и вызываем из объектного обработчика и триггера соотвественно.

Единственно исключение составляют если у вас для класса указан тип хранения CacheSQLStorage (где структуру глабала нужно задовать вручную), вместо дефолтного CacheSQLStorage.

Для CacheSQLStorage Каше автоматически и самостоятельно транслирует вызовы объектных обработчиков в вызов триггеров.

PS: я бы все таки рекомендовал прикупить книжку (на сайте интерсистемс есть ссылка) - ваши последующие вопросы базовые и в книге скорее всего рассмотрены
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34123886
Фотография rodb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Class Cinema.Film Extends %Library.Persistent [ ClassType =persistent ]
{
Method SetTitle() [ Private ]
{
Set ..Title = "OK"
}
Trigger OnUpdateTrigger [ Event = UPDATE ]
{
SetTitle()
}
}
Скажите пожалуста, что нада написать в триггере,
чтобы нормально откомпилировалось.
Не компилит. Ругается




Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34124965
Ptn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы всё еще путате уровни доступа.
Код триггера выполняется в SQL доступе, в котором нет открытого текущего объекта.
В отличие от объектных обработчиков %OnXXXX внутри которых, за исключением %OnDelete, доступен текущий объект и соотвественно можно использовать две точки.

Ваш же Метод ..SetTitle() является методом _экземпляра_ класса, и может быть вызван ТОЛЬКО из открытого объекта - do obj.SetTitle().

В SQL доступе (триггера) вам доступны только методы класса (ClassMethod а не Method), которые можно вызвать через конструкцию ##class(имя класса).ИмяКлассМетода(Параметры)

Можно вызвать но, вы опять забываете про это обращение к классу.
Либо с непосредственным указанием либо (с 5.0.10 и выше) через двуточечный синтаксис, который в данном случае сам преобразуется в ##class(имя класса) в момент компиляции.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
// Итого первое приближение
Trigger OnUpdateTrigger [ Event = UPDATE ]
{ 
 d ##class(Cinema.Film).SetTitle()
}
// Итого второе приближение
Trigger OnUpdateTrigger [ Event = UPDATE ]
{ 
 d ..SetTitle()
}

Но работать это не будет ибо - SetTitle() у вас Method - соответственно получите ошибку <NO CURRENT OBJECT>

Итого можно, но не _нужно_, писать

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Class Cinema.Film Extends %Library.Persistent [ ClassType =persistent ]
{
ClassMethod SetTitle(id As %String = "") [ Private ]
{
 new SQLCODE,%ROWID,%ROWCOUNT
 &SQL(UPDATE %NOTRIGGER Cinema.Film SET Title="OK" WHERE %ID=:id) 
 quit:SQLCODE= 0   1 
 quit $$$ERROR( 5001 ,"Не удалось обновить поле Title класса Cinema.Film с ID="_id)
}
Trigger OnUpdateTrigger [ Event = UPDATE ]
{
 set %ok=..SetTitle({ID})
}
}


Дополнительную информацию можно получить по данной ссылке
дока на create trigger смотрите раздел ObjectScript Trigger Code

Тоже самое вы можете получить локально - в каше встроена документация с полнотекстовым поиском
дока на create trigger НА ВАШЕЙ РАБОЧЕЙ СТАНЦИИ , при дефолтной настройке конечно.

Активнее пытайте её - она рулез.
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34125202
Фотография rodb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ptn,

общий подход ясен.
если используем SQL доступ, то нада выуживать объект средствами SQL по ID и
апдейтить его в реляционной манере.

спасибо вам за растолковку.

Хотя все это наводит на мысль что SQL Каше это своего рода
'реляционная нашлепка над объектной базой' -
точно такой же изврат как 'объектные нашлепки над
реляционными базами'




Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34125398
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rodbХотя все это наводит на мысль что SQL Каше это своего рода
'реляционная нашлепка над объектной базой' -
точно такой же изврат как 'объектные нашлепки над
реляционными базами'
Даже так: и sql и объекты - это нашлепки поверх мампс.
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34125794
Фотография rodb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Даже так: и sql и объекты - это нашлепки поверх мампс.

тады я в двойной печали.


Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34129236
CJIECAPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rodb
>Даже так: и sql и объекты - это нашлепки поверх мампс.

тады я в двойной печали.


Posted via ActualForum NNTP Server 1.3

Не вижу повода для печали. В принципе любой язык высокого уровня можно рассматривать как нашлёпку над машинным кодом - не встречал людей у которых это вызывало глубокую грусть.
По теме: мне на самом деле не приходилось сталкиваться с необходимостью создания тригеров.
Плюс каши, как мне кажется, в том что при решении конкретной подзадачи можно гибко балансировать между удобством разработки и производительностью. На пример SQL у нас используется в основном для выборки данных. Для добовления/изменения используется объектный подход - обычно пользователь в конкретный момент может работать только с небольшим объёмом данных (имеется ввиду именно их изменение), в этом случае накладные расходы на открытие/закрытие объектов фактически не заметны. Конечно если идёт речь о массовой загрузке имеет смысл использовать прямой доступ.
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34132111
Фотография rodb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Конкретно мне не нравится что при доступе по ODBC
надо лепить тригера на апдейт и дополнительно их поддерживать.
Получается что если запрограммировано событие %OnBeforeSave и тригеры не
поставлены, то можно подключится по ODBC и апдейтить базу с нарушением
целостности.

Потом люди будут бегать и искать -
Почему данные изменились а %OnBeforeSave не отработало?

Возможно выход есть в создании своей иерархии от %Persistent
и установка тригеров в базовом классе с прикручиванием событий апдейта на
%OnBeforeSave или собственные методы.

В среде Delphi/Builder ADO поверх ODBC, пожалуй единственный нормальный
способ построить приложение не отказываясь от старых наработок.





Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34137959
Фотография rodb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ptn,

вам однако спасибо за приведенный код.
роботает отлично.

Скажите пожалуста.
Тригера наследуются?


Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34137965
Фотография rodb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CJIECAPb,

>На пример SQL у нас используется в основном для выборки данных. Для
>добовления/изменения используется объектный подход

А объектно апдейты делать это как? через Vism?
А как после апдейта увидеть изменения в текущем наборе данных?



Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
%OnBeforeSave
    #34138311
Ptn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Триггера наследуются - но! нужно учитывать что если вы использовали прямое указание

##class(имя класса) - то и в триггере базового и в его предках будет вызываться метод именно этого класса.

Для обхождения ситуации рекомендую использовать две точки - но, как я уже говорил оно работает только с 5.0.10.

Либо писать триггера с использованием {%%CLASSNAME}.

Вообще по поводу наследования уже была ветка - я помнится туда что то подобное уже отвечал.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / %OnBeforeSave
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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