14.10.2009, 23:33 | #21 |
Administrator
|
Цитата:
Оформлено это просто в класс - чтобы можно было этот код убрать из ветки Jobs, как код, полезный при постепенном внедрении. Ну и конечно - добавлен интерфейс указания компаний для возможности использования консультантами этого джобика. Пункт меню сделан (в xpo я его не стал вкладывать)
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 14.10.2009 в 23:36. |
|
14.10.2009, 23:46 | #22 |
Боец
|
А целостность данных?
Почему бы просто не сохранить данные в буфер, переключить компанию и вставить данные. Примерно так: X++: static void copy2company(Args _args) { InventTable tmpInventTable, fromInventTable, toInventTable; ; tmpInventTable.setTmp(); fromInventTable.skipDataMethods(true); while select fromInventTable { tmpInventTable.clear(); buf2buf(fromInventTable, tmpInventTable); tmpInventTable.insert(); } ttsbegin; changecompany ("DMO") { while select tmpInventTable { toInventTable.clear(); buf2buf(tmpInventTable, toInventTable); if (toInventTable.validateWrite()) toInventTable.insert(); } } ttscommit; } Последний раз редактировалось DSPIC; 15.10.2009 в 00:12. |
|
15.10.2009, 00:26 | #23 |
Administrator
|
Цитата:
Переход в другую компанию, которая уже входит в виртуальную - это конечно вариант - но... ее может и не быть, например, мы решили объединить ряд компаний и создать новую виртуальную компанию. Кстати, обращаю внимание, что нельзя перейти в саму виртуальную компанию. Можно только перейти в компанию, входящую в состав виртуальной. На самом деле - мы отвлеклись от темы. Я привел пример - не для того, чтобы показать как это работает с виртуальными компаниями, а для того, чтобы показать, что прямое обращение к БД при замене dataAreaId если все делать по-честному - выливается не в одну строчку кода. И даже наоборот - мой вариант по сути применим только тогда, когда штатно (по аналогии как Вы показали) невозможно этого добиться. Хотя с т.з. функциональности оба примера работают одинаково - никакой целостности данных нигде не нарушается если нет связок по RecID (а если есть, то нарушается и там и там) Кстати, Ваш код работать не будет. После changecompany временная таблица тоже ведь сменит компанию. Или я не понял хитрого хода конем?
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 15.10.2009 в 00:35. |
|
15.10.2009, 06:48 | #24 |
Сам.AX
|
Цитата:
Джоб действительно работать не захотел. Сделали напрямую через SQL. Задача решена. Спасибо. |
|
15.10.2009, 09:10 | #25 |
Administrator
|
Цитата:
Так что если в будущем будет потребность повторить "на бис" процедуру - можно им будет воспользоваться
__________________
Возможно сделать все. Вопрос времени |
|
15.10.2009, 10:19 | #26 |
Сам.AX
|
Цитата:
Через SQL, говорят, могут возникнуть трудности в дальнейшем. Последний раз редактировалось Alexx7; 15.10.2009 в 10:21. Причина: Про SQL |
|
15.10.2009, 11:18 | #27 |
Боец
|
Цитата:
Кстати, Ваш код работать не будет. После changecompany временная таблица тоже ведь сменит компанию. Или я не понял хитрого хода конем?
Цитата:
Джоб действительно работать не захотел.
|
|
|
За это сообщение автора поблагодарили: sukhanchik (2). |
15.10.2009, 12:07 | #28 |
Сам.AX
|
Цитата:
Сообщение (14:06:50) Сбой запроса на разрешение типа "SqlStatementExecutePermission". (S)\Classes\SqlStatementExecutePermission\demand (S)\Classes\Statement\executeQuery (C)\Classes\ReplaceDataAreaId\updateTableRows - line 31 (C)\Classes\ReplaceDataAreaId\updateTables - line 28 (C)\Classes\ReplaceDataAreaId\run - line 19 (C)\Classes\ReplaceDataAreaId\main - line 7 Чего то скорее всего не хватает. |
|
15.10.2009, 13:07 | #29 |
Administrator
|
Ну я ж сказал
Цитата:
(C)\Classes\ReplaceDataAreaId\updateTableRows - line 31 вставить new SqlStatementExecutePermission('sql-запрос').assert(); а после строчки - CodeAccessPermission::revertAssert(); Либо отключить параметр caslevel (установить его в значение disable) в конфигурации АОСа (это в реестре) и перезапустить АОС. Лучше первый вариант - он правильнее. Опять-таки - джоб предлагался на условии идеи - т.е. на первых порах мы пермишны отключили, а потом джоб забыли поднять Проверю -отпишусь
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: Poleax (3). |
15.10.2009, 13:09 | #30 |
Administrator
|
Цитата:
Поэкспериментирую.
__________________
Возможно сделать все. Вопрос времени |
|
15.10.2009, 14:58 | #31 |
Участник
|
Еще нужно учесть, что SqlStatementExecutePermission разрешен только на стороне сервера, поэтому нужно в классе изменить свойство RunOn = Server, либо добавить статический серверный конструктор...
|
|
16.10.2009, 00:18 | #32 |
Administrator
|
Обновил XPO. Теперь он с разрешениями. Да, и необходимо учесть замечание выше по поводу RunOn=Server и сделать соответствующий пункт меню с RunOn=Server
__________________
Возможно сделать все. Вопрос времени |
|
16.10.2009, 06:37 | #33 |
Участник
|
Цитата:
На самом деле метод overwriteSystemfields() предназначен для другого - изменить значения системных полей у вновь создаваемых записей. Ниже пример, таблица Test - имеет одно текстовое поле ItemId. X++: static void SRF_Test(Args _args) { Test test; ; test.ItemId = 'dmo'; test.overwriteSystemfields(true); test.(fieldNum(Test, DataAreaId)) = 'dmo'; test.insert(); }
__________________
Sergey Nefedov |
|
|
За это сообщение автора поблагодарили: lev (4), S.Kuskov (1). |
16.10.2009, 09:29 | #34 |
Administrator
|
Цитата:
Цитата:
Более того - их можно изменить X++: static void Job(Args _args) { VendTable vendTable; ; ttsbegin; select forupdate vendTable; info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy)); vendTable.overwriteSystemfields(true); vendTable.(fieldnum(VendTable, modifiedBy)) = 'zzzz'; vendTable.doUpdate(); ttscommit; info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy)); } При этом пользователя zzzz может не существовать в базе DAX 4.0 SP2
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 16.10.2009 в 09:41. |
|
16.10.2009, 09:48 | #35 |
Сам.AX
|
sukhanchik,
Колупаю Ваш обновленный джоб. Уходит в ошибку в строрчке: X++: rst = stmt.executeQuery(sSQL); [s]\Classes\Statement\executeQuery (0) [c]\Classes\ReplaceDataAreaId\updateTableRows (39) [c]\Classes\ReplaceDataAreaId\updateTables (28) [c]\Classes\ReplaceDataAreaId\run (19) [c]\Classes\ReplaceDataAreaId\main (7) Что ещё можно посмотреть, чтобы он отработал. Спасибо. |
|
16.10.2009, 09:57 | #36 |
Участник
|
Цитата:
Сообщение от sukhanchik
А с чего Вы взяли?
Вот это неправда. На поля modified* вполне можно таким образом воздействовать. Они не изменятся при вызове update если вызвать overwriteSystemFields(true). Более того - их можно изменить X++: static void Job(Args _args) { VendTable vendTable; ; ttsbegin; select forupdate vendTable; info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy)); vendTable.overwriteSystemfields(true); vendTable.(fieldnum(VendTable, modifiedBy)) = 'zzzz'; vendTable.doUpdate(); ttscommit; info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy)); } При этом пользователя zzzz может не существовать в базе DAX 4.0 SP2 У меня на DAX 4.0 TAP 3(виртуалка по 4-ке от МС) Ваш job не изменил значение поля modifiedBy. То, что выводится в инфолог, еще не значит, что значения изменились в таблице. Поставьте перед вторым info или посмотрите значение в базе X++: vendTable.reread();
__________________
Sergey Nefedov |
|
16.10.2009, 10:34 | #37 |
Administrator
|
Цитата:
X++: static void Job(Args _args) { VendTable vendTable; ; ttsbegin; select forupdate vendTable; info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy)); ttscommit; return; vendTable.overwriteSystemfields(true); vendTable.Address += ' '; vendTable.(fieldnum(VendTable, modifiedBy)) = 'zzzz'; vendTable.doUpdate(); ttscommit; info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy)); vendTable.reread(); info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy)); }
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: SRF (1). |
16.10.2009, 11:56 | #38 |
Administrator
|
Цитата:
Сообщение от Alexx7
sukhanchik,
Колупаю Ваш обновленный джоб. Уходит в ошибку в строрчке: X++: rst = stmt.executeQuery(sSQL); [s]\Classes\Statement\executeQuery (0) [c]\Classes\ReplaceDataAreaId\updateTableRows (39) [c]\Classes\ReplaceDataAreaId\updateTables (28) [c]\Classes\ReplaceDataAreaId\run (19) [c]\Classes\ReplaceDataAreaId\main (7) Что ещё можно посмотреть, чтобы он отработал. Спасибо.
__________________
Возможно сделать все. Вопрос времени |
|
16.10.2009, 13:44 | #39 |
Сам.AX
|
Извиняюсь:
Сообщение (15:43:40) Сбой запроса на разрешение типа "SqlStatementExecutePermission". (S)\Classes\SqlStatementExecutePermission\demand (S)\Classes\Statement\executeQuery (C)\Classes\ReplaceDataAreaId\updateTableRows - line 39 (C)\Classes\ReplaceDataAreaId\updateTables - line 28 (C)\Classes\ReplaceDataAreaId\run - line 19 (C)\Classes\ReplaceDataAreaId\main - line 7 |
|
16.10.2009, 17:02 | #40 |
Administrator
|
Хм.. у меня не выругался. Сделал на всякий случай отдельную переменную Statement в методе updateTableRows на каждый вызов. XPO обновил - попробуйте.
Обратите внимание - все ли вызовы executeQuery обрамлены в new SqlStatementExecutePermission(sSQL).assert() и CodeAccessPermission::revertAssert() ? Тот ли запрос sSQL передается в SqlStatementExecutePermission, что и в executeQuery ?
__________________
Возможно сделать все. Вопрос времени |
|
Теги |
update_recordset, законченный пример, как правильно, полезное, системые поля |
|
|