Список форумов Акцент Акцент
официальный форум разработчика программы Акцент
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Преобразование базы данных из DAO в SQL
На страницу 1, 2, 3  След.
 
Начать новую тему   Ответить на тему    Список форумов Акцент -> Акцент 7.40
Предыдущая тема :: Следующая тема  
Автор Сообщение
nikman



Зарегистрирован: 10.03.2005
Сообщения: 786
Откуда: Украина, Донецк

СообщениеДобавлено: Пн Окт 22, 2012 2:54 pm    Заголовок сообщения: Преобразование базы данных из DAO в SQL Ответить с цитатой

Добрый день!

На днях предстоит преобразовать базу данных формата 7.0 DAO в формат 7.40 SQL
Может кто даст пару добрых советов.
Например, что лучше, переносить в совершенно чистую базу и накатывать решение потом.
Тут вопрос, захочет ли решение устанавливаться, оно и так уже стоит.

Или взять чистую базу с установленным решением и туда перенести данные.
Тут вопрос, как подружатся существующие данные решения с данными самой базы.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail AIM Address MSN Messenger
kris



Зарегистрирован: 12.01.2006
Сообщения: 371

СообщениеДобавлено: Пн Окт 22, 2012 4:08 pm    Заголовок сообщения: Ответить с цитатой

It all depends... (c)

Если в решении есть привязка к ИД или если есть неявные связи вроде Op.Params("Long1") = Op2.ID, то только тупым переносом данных с сохранением ИДшников.
Занимался таким года 3 назад в последний раз, алгоритм примерно такой:
1. Создаем пустую сиквельную базу
2. Накатываем структуру
3. Переносим все специфичные хранимки и (если есть) добавляем пользовательские поля/таблицы
4. Перегоняем данные в каждой таблице с предварительным отключением идентификаторов (делается по-таблично, т.к. отключить можно только для 1 таблицы одновременно). Подробностей уже не помню, если скрипт сохранился - брошу сюда.

Всего вермени заняло полу-вручную часа 2-3, не считая написания скриптов, в процессе коего изучил много интересного :)

Из подводных камней - структура некоторых таблиц немного отличается (подробностей, опять-таки не помню), допиливал руками, добавляя нужные колонки (и дефолтные значения) в исходную базу.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
kris



Зарегистрирован: 12.01.2006
Сообщения: 371

СообщениеДобавлено: Пн Окт 22, 2012 4:14 pm    Заголовок сообщения: Ответить с цитатой

Да, забыл сказать, сначала базу перегоняем целиком в сиквел без констрейнтов и всего прочего - голые данные, чтобы скрипты удобно юзать было.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
kris



Зарегистрирован: 12.01.2006
Сообщения: 371

СообщениеДобавлено: Пн Окт 22, 2012 4:25 pm    Заголовок сообщения: Ответить с цитатой

Скрипт "as is". За возможные ошибки ногами не пинать - не уверен, что это окончательный вариант, но на мысли явно должен натолкнуть Smile :
Код:
declare @db_from varchar(16)
declare @db_to varchar(16)
declare @tbl_name varchar(20)
declare @cols varchar(2000)
declare @sql varchar(8000)

set @db_from = 'ForImport4'
set @db_to = 'GarantSystem'
--set @tbl_name = 'AG_BANKS'


-- подготовительные работы с исходной базой
print 'подготовительные работы с исходной базой'
set @sql = 'alter table ' + @db_from + '.dbo.SYS_LOG add FLAGS1 int null'
exec(@sql)
set @sql = 'alter table ' + @db_from + '.dbo.SYS_LOG add SYS_ACTION nchar(1) null'
exec(@sql)
set @sql = 'update ' + @db_from + '.dbo.SYS_LOG set SYS_ACTION = ACTION'
exec(@sql)
set @sql = 'alter table ' + @db_from + '.dbo.SYS_LOG drop column ACTION'
exec(@sql)
set @sql = 'alter table ' + @db_from + '.dbo.SYS_LOG alter column SYS_ACTION nchar(1) not null'
exec(@sql)
set @sql = 'alter table ' + @db_from + '.dbo.SYS_LOG drop column UID'
exec(@sql)
set @sql = 'alter table ' + @db_from + '.dbo.SYS_LOG add UID smallint null'
exec(@sql)
set @sql = 'update ' + @db_from + '.dbo.SYS_LOG set UID = ' + cast(user_id('_Admin') as varchar)
exec(@sql)
set @sql = 'update ' + @db_from + '.dbo.JOURNAL set J_QTY = 0 where J_QTY is null'
exec(@sql)
set @sql = 'update ' + @db_from + '.dbo.JOURNAL set JF_QTY = 0 where JF_QTY is null'
exec(@sql)
set @sql = 'delete from ' + @db_from + '.dbo.JRN_TAX'
exec(@sql)
set @sql = 'update ' + @db_from + '.dbo.MENU_ACTIONS set MA_NAME = left(MA_NAME,50)'
exec(@sql)
set @sql = 'update ' + @db_from + '.dbo.MENU_ACTIONS set MA_FILE = left(MA_FILE,50)'
exec(@sql)

-- подготовительные работы с новой базой
print 'подготовительные работы с новой базой'
set @sql = 'alter table ' + @db_to + '.dbo.DOCUMENTS alter column DOC_PS1 nvarchar(255) null'
exec(@sql)
set @sql = 'alter table ' + @db_to + '.dbo.DOCUMENTS alter column DOC_PS2 nvarchar(255) null'
exec(@sql)
set @sql = 'alter table ' + @db_to + '.dbo.DOCUMENTS alter column DOC_PS3 nvarchar(255) null'
exec(@sql)
--set @sql = 'alter table ' + @db_to + '.dbo.AG_BANKS drop constraint PK_AG_BANKS'
--exec(@sql)


-- объявим курсор для всех таблиц
declare Cur cursor for
select   NAME
from   sys.sysobjects
where   TYPE = 'U'
order by NAME

open Cur

fetch next from Cur
into @tbl_name

while @@FETCH_STATUS = 0
begin
   print @tbl_name
   set @cols = ''
   set @sql = ''
   select @cols = @cols + name + ',' from syscolumns where object_name(id)=@tbl_name
   set @cols = left(@cols, len(@cols)-1)
   if exists (select * from syscolumns where object_name(id) = @tbl_name and status = 0x80)
   begin
      set @sql = @sql + ' set IDENTITY_INSERT ' + @db_to + '.dbo.' + @tbl_name + ' on'
      print 'has identity column...'
   end
   set @sql = @sql +
            ' insert into ' + @db_to + '.dbo.' + @tbl_name + '(' + @cols + ')' +
            ' select ' + @cols +
            ' from ' + @db_from + '.dbo.' + @tbl_name
   if exists (select * from syscolumns where object_name(id) = @tbl_name and status = 0x80)
   begin
      set @sql = @sql + ' set IDENTITY_INSERT ' + @db_to + '.dbo.' + @tbl_name + ' off'
   end
   exec(@sql)
   fetch next from Cur
   into @tbl_name
end

close Cur
deallocate Cur
--set @sql = 'alter table ' + @db_to + '.AG_BANKS WITH NOCHECK ADD CONSTRAINT PK_AG_BANKS PRIMARY KEY  NONCLUSTERED (AB_PK) ON PRIMARY'

set @tbl_name = 'AG_BANKS'
   print @tbl_name
   set @cols = ''
   set @sql = ''
   select @cols = @cols + name + ',' from syscolumns where object_name(id)=@tbl_name
   set @cols = left(@cols, len(@cols)-1)
   if exists (select * from syscolumns where object_name(id) = @tbl_name and status = 0x80)
   begin
      set @sql = @sql + ' set IDENTITY_INSERT ' + @db_to + '.dbo.' + @tbl_name + ' on'
      print 'has identity column...'
   end
   set @sql = @sql +
            ' insert into ' + @db_to + '.dbo.' + @tbl_name + '(' + @cols + ')' +
            ' select ' + @cols +
            ' from ' + @db_from + '.dbo.' + @tbl_name
   if exists (select * from syscolumns where object_name(id) = @tbl_name and status = 0x80)
   begin
      set @sql = @sql + ' set IDENTITY_INSERT ' + @db_to + '.dbo.' + @tbl_name + ' off'
   end
   exec(@sql)

set @tbl_name = 'JOURNAL'
   print @tbl_name
   set @cols = ''
   set @sql = ''
   select @cols = @cols + name + ',' from syscolumns where object_name(id)=@tbl_name
   set @cols = left(@cols, len(@cols)-1)
   if exists (select * from syscolumns where object_name(id) = @tbl_name and status = 0x80)
   begin
      set @sql = @sql + ' set IDENTITY_INSERT ' + @db_to + '.dbo.' + @tbl_name + ' on'
      print 'has identity column...'
   end
   set @sql = @sql +
            ' insert into ' + @db_to + '.dbo.' + @tbl_name + '(' + @cols + ')' +
            ' select ' + @cols +
            ' from ' + @db_from + '.dbo.' + @tbl_name
   if exists (select * from syscolumns where object_name(id) = @tbl_name and status = 0x80)
   begin
      set @sql = @sql + ' set IDENTITY_INSERT ' + @db_to + '.dbo.' + @tbl_name + ' off'
   end
   exec(@sql)

update   SYS_PARAMS
set      PRM_STR = '7.0', PRM_LONG = 297
where   PRM_NAME = 'VERSION'
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Юров Ю.С.



Зарегистрирован: 11.03.2005
Сообщения: 383
Откуда: Павлоград

СообщениеДобавлено: Пн Окт 22, 2012 6:04 pm    Заголовок сообщения: Re: Преобразование базы данных из DAO в SQL Ответить с цитатой

nikman писал(а):
что лучше, переносить в совершенно чистую базу и накатывать решение потом.
Тут вопрос, захочет ли решение устанавливаться, оно и так уже стоит.

Возможность повторной установки решения(цепочки обновлений) трудно реализуется, поэтому даже если таковая предусмотрена разработчиками, лучше не надеяться что сработает безупречно.

nikman писал(а):
Или взять чистую базу с установленным решением и туда перенести данные.
Тут вопрос, как подружатся существующие данные решения с данными самой базы.

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

Предлагаю ещё один вариант перевода DAO-SQL, поскольку тема весьма актуальна всвязи с развитием А2.

Модуль запускается из открытой в Акценте чистой (или образцовой) SQL-ной базы данных.
Очищает все таблицы открытой базы данных Акцента, открывает диалог выбора файла базы DAO, после чего копирует данные из таблиц DAO в SQL.
Давно им не пользовался, поэтому тоже as-is. Чем лучше DTS - c DTS придётся повозиться, а этот модуль с большой вероятностью даст результат сразу.
Модуль копирует столбцы по их наличию в DAO таблицах, значит можно переносить данные из 6,7 версии в 7.40, но этой возможностью лучше не злоупотреблять, а перевести DAO-базу Акцентом-DAO соответствующей версии. Столбцы, добавленные в решении, должны существовать в SQL-ьных таблицах, т.е. решение должно быть накатано в обоих базах.

Из текста протокола работы модуля можно сделать чистый SQL-скрипт переноса данных путём удаления информационных сообщений.

Слегка доработанная версия находится здесь
http://www.nansi.com.ua/44058109/DAO-SQL.rar
Добавлен обход ограничения UNIQ_ACC_TREE, убрана авторизация в DAO-базе, работа проверена на нескольких базах.


Последний раз редактировалось: Юров Ю.С. (Пт Окт 26, 2012 11:24 am), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Jeck



Зарегистрирован: 17.05.2005
Сообщения: 171
Откуда: Донецк

СообщениеДобавлено: Ср Окт 24, 2012 5:33 pm    Заголовок сообщения: Ответить с цитатой

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

1. создаем новую базу со структурой
2. вычищаем все данные из таблицы валют и параметров базы данных (т.е. все таблицы д.б. пустыми)
3. переносим только основные справочники и названия параметров
4. подкидываем деревья к ним и прочие справочники
5. деревья к прочим справочникам
6. потихоньку все оставшиеся таблицы

при импорте таблиц ОБЯЗАТЕЛЬНО указывать переносить ключи как есть(не помню точное название галочки)

перед импортом таблицы JOURNAL необходимо поля j_qty и еще одно поле тоже с qty все что is null присвоить 0

Very Happy Very Happy удачи
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
AllexL



Зарегистрирован: 10.03.2005
Сообщения: 434
Откуда: Donetsk

СообщениеДобавлено: Ср Окт 24, 2012 6:25 pm    Заголовок сообщения: Ответить с цитатой

Jeck писал(а):

при импорте таблиц ОБЯЗАТЕЛЬНО указывать переносить ключи как есть(не помню точное название галочки)

set identity insert <tablename> on/off;
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Jeck



Зарегистрирован: 17.05.2005
Сообщения: 171
Откуда: Донецк

СообщениеДобавлено: Чт Окт 25, 2012 6:48 am    Заголовок сообщения: Ответить с цитатой

AllexL писал(а):
Jeck писал(а):

при импорте таблиц ОБЯЗАТЕЛЬНО указывать переносить ключи как есть(не помню точное название галочки)

set identity insert <tablename> on/off;

Very Happy У меня манагер русский - разрешить вставку в столбец индификаторов.
проверил записи: 2 - 4 часа, все зависит от базы.
этот параметр необходимо проставлять при импорте каждой таблицы через ИЗМЕНИТЬ
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
kris



Зарегистрирован: 12.01.2006
Сообщения: 371

СообщениеДобавлено: Чт Окт 25, 2012 8:56 am    Заголовок сообщения: Ответить с цитатой

Jeck писал(а):
я это делал много раз и каждый раз полностью руками.
времени тратится примерно пол дня.

А чем скрип-то плох? Тем более, если делать это надо часто. Вручную что-то пропустил и ... Если делаете часто, берите мой или товарища Юрова, дорабатывайте все возможные нюансы и выкладываете в общее достояние Smile)
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Jeck



Зарегистрирован: 17.05.2005
Сообщения: 171
Откуда: Донецк

СообщениеДобавлено: Чт Окт 25, 2012 5:17 pm    Заголовок сообщения: Ответить с цитатой

kris писал(а):
Jeck писал(а):
я это делал много раз и каждый раз полностью руками.
времени тратится примерно пол дня.

А чем скрип-то плох? Тем более, если делать это надо часто. Вручную что-то пропустил и ... Если делаете часто, берите мой или товарища Юрова, дорабатывайте все возможные нюансы и выкладываете в общее достояние Smile)

... повторный экспорт бессмысленен, вроде в SQL не так жёстко со ссылочной целостностью как в DAO ...

вот из-за этой фразы.
я столкнулся наоборот.
импорт д.б. только поэтапным

когда делал в первый раз, то не во всех таблицах поставил эту галочку и тоже начинал с импорта в чистую базу без структуры акцента. Ох и намучался
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
nikman



Зарегистрирован: 10.03.2005
Сообщения: 786
Откуда: Украина, Донецк

СообщениеДобавлено: Пт Окт 26, 2012 5:56 am    Заголовок сообщения: Ответить с цитатой

Добрый день!

Спасибо всем за советы. Вроде получилось.
Расскажу по порядку, как все было. С самого начала.

1. Заказ ПО.
Юридическое лицо, на которое оформлена старая лицензия, уже давно не существует.
Но Импакту это сложно понять, поэтому он делает новую лицензию на несуществующую фирму.
Глупость? Ну да ладно, переживем.

2. Покупка ПО.
Казалось бы, ничего сложного.
Есть лицензия на Акцент 7.0 DAO 3 р.м.
Фирма переходит на Акцент 7.40 SQL 3 р.м.
Считаем стоимость нового ПО, делаем скидку 35% и все. Не тут-то было.
Оказывается скидку можно делать только на сумму Акцент 7.40 DAO.
А переход от DAO на SQL -- уже без скидки.
Выставил клиенту честную цену. Импакту доплатил из своих. Не обеднею.
В платежке так и написал: "доплата за обман и жадность".

3. Установка SQL Server.
SQL Server 2012 не захотел ставиться на Windows Server 2003.
Ладно, скачал SQL Server 2008 Express.
Блин, где же SQL Server Managment Studio (средства управленя БД)?
Ага, нужно скачать Express with Tools. Ок.
Блин, ну где же SQL Server Managment Studio?!
Ага, нужно скачать отдельно Express Managment Studio.
Ладно, заморочки MS поборол.

4. Перенос данных. Собственно.
Первым делом обновил DAO-базу до формата 7.40. На всякий случай.
Создал SQL-базу, запустил скрипт "script74_404.sql".
Переносить решил стандартными средствами SQL Server DTS.
В настройках DTS включил для всех таблиц "вставлять идентификаторы"
Остальное DTS сам сделал.

4.1 SQL-база не пустая.
Скрипт, который должен создавать пустую базу, создает не совсем пустую базу.
В конце делает записи в т. CURRENCIES и в т. SYS_PARAMS
DTS ругается, что существует записи с одинаковыми ID.
Закомментировал.
4.2 Ярлыки.
В таблице ACC_TREE стоит ограничение записи с одинаковыми полями ID и P0.
Но ведь как раз такие записи и создаются ярлыками. Странно.
Пришлось удалить все ярлыки в плане счетов.
4.3 Таблица ENTITIES
Откуда-то затесался ОУ с именем NULL. Удалил.
4.4 Таблица JOURNAL
Оказывается поле J_QTY не может быть NULL!
Очень неожиданно! Таких записей в любой базе примерно половина.
Пришлось скрипт создания базы еще подредактировать.
Убрал ограничение J_QTY not NULL.
4.5 Таблица SYS_LOG
В SQL-базе поле UID имеет тип smallint,
а в DAO-базе там везде стоит "admin". Загадочно.
Почистил логи. Надо было сразу это сделать.

Ура! Экспорт завершен успешно!

Но при запуске Акцент выдает какое-то странное сообщение
"Папку нельзя удалить, поскольку она используется в форме или диалоге... и т.д."
Удивился.
Вспомнил, что в скрипте создания базы комментировал добавление строк в таблицу SYS_PARAMS.
Исправил строку VERSION 6.0 202 на VERSION 7.4 404.
Помогло.

5. Напослелок запустил установку решения Казначея последней версии,
чтобы оно создало в новой базе все, чего ему надо.

Посмотрим, что получилось.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail AIM Address MSN Messenger
kris



Зарегистрирован: 12.01.2006
Сообщения: 371

СообщениеДобавлено: Пт Окт 26, 2012 8:56 am    Заголовок сообщения: Ответить с цитатой

П. 4.4 - неправильно сделали. Может все и нормально будет, но 0<>null. Надо было все нулы земенить нулями, а то в будущем может непредсказуемо где-то вылезти. А может и не вылезти. Тут только Кухтин может точно сказать Smile
Ну а по поводу остальных проблем - так они вроде достаточно описаны в данных вам скриптах?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
kris



Зарегистрирован: 12.01.2006
Сообщения: 371

СообщениеДобавлено: Пт Окт 26, 2012 9:03 am    Заголовок сообщения: Ответить с цитатой

Jeck писал(а):
... повторный экспорт бессмысленен, вроде в SQL не так жёстко со ссылочной целостностью как в DAO ...

вот из-за этой фразы.
я столкнулся наоборот.
импорт д.б. только поэтапным

когда делал в первый раз, то не во всех таблицах поставил эту галочку и тоже начинал с импорта в чистую базу без структуры акцента. Ох и намучался


Не одну и ту же базу несколько раз выгружать, а разные базы. По крайней мере из ваших слов я понял именно так.

А по поводу identity_insert так мне и вовсе не понятно:
Цитата:
At any time, only one table in a session can have the IDENTITY_INSERT property set to ON. If a table already has this property set to ON, and a SET IDENTITY_INSERT ON statement is issued for another table, Microsoft® SQL Server™ returns an error message that states SET IDENTITY_INSERT is already ON and reports the table it is set ON for.

И именно в этом проблема, и именно потому я в курсоре включаю/выключаю его потаблично.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Юров Ю.С.



Зарегистрирован: 11.03.2005
Сообщения: 383
Откуда: Павлоград

СообщениеДобавлено: Пт Окт 26, 2012 11:11 am    Заголовок сообщения: Ответить с цитатой

Jeck писал(а):
... повторный экспорт бессмысленен, вроде в SQL не так жёстко со ссылочной целостностью как в DAO ...

вот из-за этой фразы.
я столкнулся наоборот.
импорт д.б. только поэтапным

Это в мой адрес замечание.
Следует уточнить: "не так жёстко со ссылочной целостностью как в DAO" относиться только к базам, сформированным скриптом struct_7x_xxx.sql, если запускался скрипт ссылочной целостности DRI - придётся ту же таблицу DOCUMENTS копировать по частям, сначала родительские документы, после документы которые на них ссылаются по полю DOC_LINK.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
kris



Зарегистрирован: 12.01.2006
Сообщения: 371

СообщениеДобавлено: Пт Окт 26, 2012 1:38 pm    Заголовок сообщения: Ответить с цитатой

Ну тогда можно еще немного извратиться и накатить структуру в 2 этапа: сначала только структуру таблиц, потом собственно импорт данных, а уж после накатывать индексы, ключи и все такое. Если не ошибаюсь, именно чтобы не делать этого, я прогонял все таблицы, получал ошибки на банках (ссылается на корреспондентов) и джорнале (ссылается на все, на что может), клал на эти ошибки и просто в скрипт дописал в конце заполнение этих таблиц. Некрасиво, конечно, но работает Smile
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов Акцент -> Акцент 7.40 Часовой пояс: GMT + 2
На страницу 1, 2, 3  След.
Страница 1 из 3

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2005 phpBB Group