|
20.10.2014, 16:04 | #1 |
Участник
|
Подмена запроса для View
Добрый день.
Имеется созданное в AOT View определенной структуры. Задача - подменить содержимое View на уровне базы данных. В Axapta 3 (+Oracle) данная задача решалась написанием скрипта (CREATE OR REPLACE VIEW...) в SysSQLInitDbTriggers. Как решается данная задача в DAX2009? Пересмотрел на форуме множество тем, в которых говорится, что необходима доработка при синхронизации или что нужно смотреть в сторону Application::dbSynchronize() (в том числе смотрел тему Запрет синхронизации объекта АОТ). В итоге однозначного решения не нашел. Если кто-нибудь знает решение для DAX2009 или есть пример решения, просьба рассказать о нем.
__________________
С уважением, Александр. Последний раз редактировалось samolalex; 20.10.2014 в 17:39. |
|
22.10.2014, 10:50 | #2 |
Участник
|
Цитата:
для MS SQL вместо CREATE OR REPLACE VIEW... будет Код: IF OBJECT_ID ('[myViewName]',\'V\') IS NOT NULL DROP VIEW [myViewName] CREATE VIEW [myViewName] ... |
|
|
За это сообщение автора поблагодарили: Logger (3), samolalex (2). |
22.10.2014, 12:10 | #3 |
Участник
|
Вопрос вызывает место (класс/метод), из которого необходимо вызывать скрипт, т.к. в DAX2009 SysSQLInitDbTriggers отсутствует.
__________________
С уважением, Александр. |
|
22.10.2014, 11:47 | #4 |
Участник
|
Можно через класс Application, метод dbSynchronize с подменой запроса для конкретного View.
__________________
Айрат Вильданов. skype: vildanov.a |
|
22.10.2014, 11:55 | #5 |
Участник
|
А что подразумевается под подменой запроса в данном случае - вызов скрипта "CREATE VIEW..."? И как именно можно подменить запрос для конкретного VIEW?
__________________
С уважением, Александр. |
|
22.10.2014, 12:36 | #6 |
Участник
|
Цитата:
X++: ok = super(tableId, syncAsNeeded, continueOnError, showProgress, checkSyncTables); X++: private void CreateView(str _sql) { Connection connection; Statement statement; ; connection = new Connection(); statement = connection.createStatement(); SqlStatementExecutePermission = new SqlStatementExecutePermission ( _sql ); SqlStatementExecutePermission.assert(); statement.executeUpdate(_sql); CodeAccessPermission::revertAssert(); } Перед созданием вьюшки - ее надо грохнуть.
__________________
Айрат Вильданов. skype: vildanov.a |
|
|
За это сообщение автора поблагодарили: samolalex (2). |
22.10.2014, 15:46 | #7 |
Участник
|
Спасибо за ответы.
Правильно я понимаю (с учетом информации в ранее опубликованной теме Синхронизация View DAX40), что при синхронизации определенного VIEW в метод Application::dbSynchronize() параметр tableId всегда передается равным 0. т.е. получается, что определить синхронизация какого объекта происходит в указанном методе невозможно?
__________________
С уважением, Александр. Последний раз редактировалось samolalex; 22.10.2014 в 16:07. |
|
22.10.2014, 16:13 | #8 |
Участник
|
Цитата:
Сообщение от samolalex
Спасибо за ответы.
Правильно я понимаю (с учетом информации в ранее опубликованной теме Синхронизация View DAX40), что при синхронизации определенного VIEW в метод Application::dbSynchronize() параметр tableId всегда передается равным 0. т.е. получается, что определить синхронизация какого объекта происходит в указанном методе невозможно? |
|
22.10.2014, 12:25 | #9 |
Участник
|
|
|
08.07.2015, 09:20 | #10 |
Участник
|
Никому не удалось исключить таблицу из синхронизации в AX2009 ? Очень нужно!
|
|
08.07.2015, 09:46 | #11 |
Участник
|
Никогда не было такой задачи.
Вот индексы успешно прятали от аксапты. Возможно для табличек сработает такой же подход. А вам это зачем ? |
|
08.07.2015, 09:54 | #12 |
Участник
|
Всё та же задача - подменить содержимое View на уровне базы данных. Создано представление в рабочей базе, которое связано с таблицей в другой базе. В рабочей базе в SQL данная таблица удалена и при синхронизации в программе выдается ошибка по этой таблице. Поэтому нужно исключить её из синхронизации.
|
|
08.07.2015, 09:54 | #13 |
Участник
|
Вот тема была для индексов
Не удалять индексы при синхронизации |
|
08.07.2015, 10:01 | #14 |
Участник
|
Подложите во View копию этой таблицы, просто что бы ошибки не было. А после все равно подмените текст View на свой.
|
|
08.07.2015, 10:16 | #15 |
Участник
|
А как в SQL подложить во View копию этой таблицы?
|
|
08.07.2015, 10:35 | #16 |
Участник
|
Если нет необходимости в подмене view сразу после синхронизации, можно все сделать средствами самого sql - сделать периодическую операцию, которая делает drop view XXX / create view XXX раз в день. И Kuskov правильно сказал про копию таблицы - обязательно сделайте, просто чтобы не было сообщений об ошибке
Последний раз редактировалось AlexeyS; 08.07.2015 в 10:37. |
|
08.07.2015, 10:46 | #17 |
Участник
|
Еще раз на примере: есть 2 базы Work и Test.
1) В приложении Test (в Axapta) создаем таблицу TestFile. При синхронизации эта таблица появляется в базе Test 2) В базе Work в SQL создаем таблицу TestFile с такой же структурой 3) В базе Test в SQL удаляем таблицу TestFile 4) В базе Test в SQL создаем представление TestFile, связанное с базой Work. Таким образом, при работе в приложении Test c таблицей TestFile данные записываются в базу Work через представление. Но при синхронизации таблиц в приложении Test возникнет ошибка, потому что мы удалили таблицу в базе Test в SQL. |
|
08.07.2015, 10:57 | #18 |
Участник
|
|
|
08.07.2015, 12:03 | #19 |
Участник
|
Цитата:
Сообщение от Dolores
Еще раз на примере: есть 2 базы Work и Test.
1) В приложении Test (в Axapta) создаем таблицу TestFile. При синхронизации эта таблица появляется в базе Test 2) В базе Work в SQL создаем таблицу TestFile с такой же структурой 3) В базе Test в SQL удаляем таблицу TestFile 4) В базе Test в SQL создаем представление TestFile, связанное с базой Work. Таким образом, при работе в приложении Test c таблицей TestFile данные записываются в базу Work через представление. Но при синхронизации таблиц в приложении Test возникнет ошибка, потому что мы удалили таблицу в базе Test в SQL. Исходная таблица TestFile в базе Test не удаляется, а переименовывается. ДО штатной синхронизации выполняется:
ПОСЛЕ штатной синхронизации выполняется:
Т.е. в конец имени таблицы через символ подчеркивания дописывается GUID сформированный через функцию NewId() на MS SQL сервере Все параметры, необходимые как для переименования, так и для создания View хранятся в специально для этого созданной настроечной таблице В "псевдокоде" это выглядит так X++: \\ \Classes\Application\dbSynchronize boolean dbSynchronize(tableId tableId = 0, ...) { MyClass_SqlView myClass_SqlView; (...) // Переименование таблиц ДО синхронизации myClass_SqlView = new MyClass_SqlView(); myClass_SqlView.restoreOrigConfig(tableId); // Собственно синхронизация ok = super(tableId, syncAsNeeded, continueOnError, showProgress, checkSyncTables); // Переименование таблиц ПОСЛЕ синхронизации myClass_SqlView.replaceTableOnView(tableId); (...) } Для MS SQL переименование - это хранимая процедура sp_rename. Использовать можно так Код: -- Скрипт MS SQL if ObjectProperty(Object_Id('Старое_Имя'), 'IsUserTable') = 1 exec sp_rename 'Старое_Имя','Новое_имя' Если в качестве параметра TableId передан 0, то переименовываются все View, имена которых хранятся в настроечной таблице Соответственно, в рабочей базе просто надо удалить записи в этой настроечной таблице, чтобы использовалась сама таблица, а не создавалось View на ее основе. View именно удаляются/создаются по той причине, что в исходную таблицу TestFile могут быть добавлены/удалены поля. Т.е. без пересоздания View может произойти рассинхронизация структуры View и таблицы-образца. Тут есть некоторая проблема, связанная с тем, что в случае модификации структуры собственно настроечной таблицы, где хранятся имена для переименования, может возникнуть конфликт при выполнении myClass_SqlView.restoreOrigConfig(). Но вероятность такого конфликта не высока, а если он все-таки возник, то лучше "вручную" синхронизировать сначала эту настроечную таблицу, и только после этого выполнять синхронизацию View. PS: У нас подобные View использовались для объединения данных из нескольких баз. Т.е. View - это Select * from Base1.dbo.Table1 UNION ALL Base2.dbo.Table1
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
08.07.2015, 10:28 | #20 |
Участник
|
Зачем через SQL? Напрямую в приложении аксапты всё сделайте.
Или я не понимаю проблемы? Допустим вам нужно в итоге получить View с определённым набором столбцов (откуда будут тянуться данные для этой View не важно). Я бы создал в этом же приложении таблицу с произвольным именем по структуре совпадающую с результирующим View (с таким же набором столбцов и соответствующими типами данных). Сделал бы на основе этой вспомогательной таблицы View с нужным именем. |
|
|
|