Автозначение первичного ключа

Автор her_mr, 24 сентября 2019, 07:58

0 Пользователи и 1 гость просматривают эту тему.

her_mr

Всем доброго времени суток!
Ничего не знаю в ЛибреОфис и скорее задам очень глупый вопрос, но так случилось, что надо перенести все данные с БД Акссес на данную.
Возникла проблема в том, что первичный ключ не получается выставить в автоинкремент, а ручками вводить постоянно - не вариант. Возможно-ли как-то изменить это, с уже имеющимся данными?
(глупый, не разобрался как вставить картинку, поэтому приложу файлик ODB самой базы и скриншоты во вложение)
Версия: 6.2.7.1 (x86), Firebird встроенная

Ошибка:
firebird_sdbc error:
*Dynamic SQL Error
*SQL error code = -104
*Token unknown - line 1, column 50
*GENERATED
caused by
'isc_dsql_prepare'

kompilainenn

Цитата: her_mr от 24 сентября 2019, 07:58Ничего не знаю в ЛибреОфис и скорее задам очень глупый вопрос, но так случилось, что надо перенести все данные с БД Акссес на данную.
Можно просто подключить БД Access в Base.

ps: я крайне не советую использовать Base в чем-то более серьезном, чем пособие по обучению самым азам баз данных=(
Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут

her_mr

Цитата: kompilainenn от 24 сентября 2019, 09:37Можно просто подключить БД Access в Base.
Я попытался, но я не могу в таком случае редактировать данные, хоть и первичный ключ есть.

Kadet

Сталкивался с подобной проблемой при подключении внешней FB.
Эта проблема решается редактированием генераторов-счётчиков с помощью SQL-запросов.

Сейчас не могу выложить коды запросов. Завтра выложу и опишу.

rami

Самый простой вариант следующий:
1. для начала нужно создать новую таблицу без данных с автоинкрементным ключом и соответствующими полями.
Код для быстрого создания таблицы (имя можно изменить). Выполнить из меню "Сервис" —> "SQL...":
CREATE TABLE "новая" ( "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, "тномер" VARCHAR(255), "Т1прич" VARCHAR(255), "Прич_реш" VARCHAR(255), "T2" VARCHAR(255), "Т2прич" VARCHAR(255), "Приоритет" VARCHAR(255), "Причина" VARCHAR(255), "НачВрем" VARCHAR(255), "НачЧас" VARCHAR(255), "КонВрем" VARCHAR(255), "КонЧас" VARCHAR(255), "КласПроблем" VARCHAR(255), "КласСер" VARCHAR(255), "УрКрит" VARCHAR(255), "СоСлов" VARCHAR(255), "Состояние" VARCHAR(255), "Заверш_Сост" VARCHAR(255), "Оператор" VARCHAR(255), "Опер закр" VARCHAR(255), "Обращение" VARCHAR(255), "ИмяПК" VARCHAR(255), "Телефон" VARCHAR(255), "Дат" VARCHAR(255), "Час" VARCHAR(255), "ЭслокДата" VARCHAR(255), "ЭслокЧас" VARCHAR(255), "Фотография" VARCHAR(255), "FileExt" VARCHAR(255), "ТипУслуги" VARCHAR(255), "НазвУслуги" VARCHAR(255), "ВиРабУсл" VARCHAR(255), "ОпРабУсл" VARCHAR(255), "Модуль" VARCHAR(255), "КлассИзм" VARCHAR(255), "Номслуже" VARCHAR(255), "При_реш_admin" VARCHAR(255), "timest" VARCHAR(255));
Чтобы увидеть созданную таблицу, в меню "Вид" нажать "Обновить таблицы".

2. перетащить старую таблицу на новую (не обязательно точно), откроется окошко "Копирование", в нём указать имя новой таблицы, и выбрать "Добавить данные".

3. жмём "Далее >" на следующую страницу "Соответствие полей".

4. снимаем "птичку" только с пункта "ID" исходной таблицы.

5. Готово!


her_mr

Цитата: rami от 25 сентября 2019, 13:32Самый простой вариант следующий:
1. для начала нужно создать новую таблицу без данных с автоинкрементным ключом и соответствующими полями.
Код для быстрого создания таблицы (имя можно изменить). Выполнить из меню "Сервис" —> "SQL...":
Код:
CREATE TABLE "новая" ( "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, "тномер" VARCHAR(255), "Т1прич" VARCHAR(255), "Прич_реш" VARCHAR(255), "T2" VARCHAR(255), "Т2прич" VARCHAR(255), "Приоритет" VARCHAR(255), "Причина" VARCHAR(255), "НачВрем" VARCHAR(255), "НачЧас" VARCHAR(255), "КонВрем" VARCHAR(255), "КонЧас" VARCHAR(255), "КласПроблем" VARCHAR(255), "КласСер" VARCHAR(255), "УрКрит" VARCHAR(255), "СоСлов" VARCHAR(255), "Состояние" VARCHAR(255), "Заверш_Сост" VARCHAR(255), "Оператор" VARCHAR(255), "Опер закр" VARCHAR(255), "Обращение" VARCHAR(255), "ИмяПК" VARCHAR(255), "Телефон" VARCHAR(255), "Дат" VARCHAR(255), "Час" VARCHAR(255), "ЭслокДата" VARCHAR(255), "ЭслокЧас" VARCHAR(255), "Фотография" VARCHAR(255), "FileExt" VARCHAR(255), "ТипУслуги" VARCHAR(255), "НазвУслуги" VARCHAR(255), "ВиРабУсл" VARCHAR(255), "ОпРабУсл" VARCHAR(255), "Модуль" VARCHAR(255), "КлассИзм" VARCHAR(255), "Номслуже" VARCHAR(255), "При_реш_admin" VARCHAR(255), "timest" VARCHAR(255));
Чтобы увидеть созданную таблицу, в меню "Вид" нажать "Обновить таблицы".

2. перетащить старую таблицу на новую (не обязательно точно), откроется окошко "Копирование", в нём указать имя новой таблицы, и выбрать "Добавить данные".

3. жмём "Далее >" на следующую страницу "Соответствие полей".

4. снимаем "птичку" только с пункта "ID" исходной таблицы.

5. Готово!

Большое спасибо! Ваш вариант мне очень помог.

Kadet

И хотя вопрошающий уже удовлетворён, я всё же выложу свою методику решения этой проблемы. Авось кому в будущем и пригодится. Тем более, как мне кажется, мой вариант гораздо проще.

Судя по скринам из старпоста в перенесённых таблицах уже имеется первичный ключ, а следовательно автоматически создан и генератор инкременции (счётчик) этого первичного ключа. Проблема заключается в том, что счётчики генераторов указывают не на последний номер первичного ключа, а куда-нибудь в начальные или срединные ID таблицы и, соответственно, следующий номер оказывается уже занят. Именно это и вызывает ошибку.
К тому же, в FB замечена некая особенность (по крайней мере во внешней БД FB) - новая запись в таблице физически может располагаться не в конце таблицы, а где-нибудь в середине, вернее там, где была удалена какая-то другая строка. FB таким образом заполняет образовавшиеся пустоты. Поэтому тут не помогают хитрости типа LAST+1.

Итак, к решению.
Открываем БД и запускаем - Сервис > SQL. Открывается утилита: "Выполнить инструкцию SQL". Здесь нужно поставить галочку в поле: "Показать вывод операторов SQL". Загоняем команды в поле "Выполняемая команда" и нажимаем "Выполнить".
Для начала нужно получить список всех генераторов своей БД. Для этого существует простой запрос:
*/Список генераторов/
SELECT * FROM RDB$GENERATORS

В поле "Вывод" будет выдана таблица результатов, а вернее выдаст весь список и  описания всех генераторов БД. У каждой таблицы есть свой один единственный генератор. Из этой кучи инфы нужно вытащить только имена существующих генераторов. Их имена будут примерно следующие: RDB$26, RDB$27, RDB$28... Все остальные генераторы, с другими именами типа: RDB$SECURITY_CLASS, SQL$DEFAULT, RDB$PROCEDURES и т.п., являются встроенными для внутренних системных таблиц и их лучше не трогать (ни под каким предлогом), ибо легко можно запороть всю БД.
Далее, нам нужно установить к какой именно таблице привязан каждый генератор. Для этого удобно получить текущие значения всех генераторов. Делается это так, меняя только имена (RDB$26) генераторов:
*/Получение текущего значения генератора/
SELECT GEN_ID(RDB$26, 0) FROM RDB$DATABASE

Если генератор стоит правильно, то полученное значение будет соответствовать или +1 от максимального ID таблицы. Если же нет, но покажет непонятную цифру, указывающую непонятно куда. Проверить желательно все таблицы. И найти соответствия генераторов таблицам. Дело, конечно, кропотливое, но оно того стоит. Эти данные могут ещё не раз помочь в будущем, как помогают периодически мне.
Если счётчики показывают не правильно, то нужно их установить правильно. Это делается следующим запросом (RDB$26 - имя генератора, 157 - устанавливаемое значение счётчика):
*/Изменение текущего значения генератора/
SET GENERATOR RDB$26 TO 157

Это и есть решение этой проблемы. Значения счётчиков по SET GENERATOR нужно устанавливать на последий существующий ID, автомат потом сам будет делать +1.

Остаётся задача - как найти соответствие генераторов таблицам. Некоторые счётчики, обычно, всё же показывают правильные значения, даже после переносов. Это соответствие можно просто увидеть по соответствию максимальному ID таблицы и значению полученному из второго запроса, чаще всего +1, потому что SELECT GEN_ID автоматически щёлкает счётчик на +1.
Ну, а те, которые неправильные следует вычислять. Для этого я брал максимальный ID из самой большой таблицы и устанавливал его значение на исследуемый генератор (SET GENERATOR). Потом поочерёдно вручную создавал новую запись в разных таблицах и там, где ID созданной мною новой записи выдаст созданный мною счётчик +1, то это и есть та самая таблица, за которую отвечает этот самый генератор. Потом запись удаляю, а счётчик генератора устанавливаю в правильное значение - равный максимальному ID этой таблицы.
И так далее, методом перебора по всем таблица.
Конечно, немного муторно и кропотливо, но после этого вы будете иметь полное понимание соответствия ваших генераторов вашим таблицам и при случае управлять ими. А случаи бывают разные.

Kadet

Однако моя метода относится к БД на Firebird и ко встроенной БД LO 6.2 и выше (где тоже FB). К другим БД может и не подойти.

jurii

kompilainenn, я крайне не советую использовать Base в чем-то более серьезном, чем пособие по обучению самым азам баз данных=(, поясните пожалуйста почему?

kompilainenn

Цитата: jurii от 27 сентября 2019, 19:30
kompilainenn, я крайне не советую использовать Base в чем-то более серьезном, чем пособие по обучению самым азам баз данных=(, поясните пожалуйста почему?
нестабильная и недоработанная эта штука. Когда оно у вас падать будет на ровном месте и уносить в ад вашу БД, вы поймете
Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут

Kadet

Как ни странно, не согласен с последними мнениями. На своём предприятии используем БД на LO 6.2 + внешняя БД на FB уже полгода. Вначале боялись и в тестовом режиме работали всего пару менеджеров. Недавно приняли решение запустить БД по полной.
Ни падений ни нестабильности не выявлено. Конечно, проблемы иной раз появляются. Скажем, при активном использовании фильтров и множественном открытий и закрытий форм начинает сильно тормозить на этой машине, при этом на других пользователей это вообще никак не влияет. Я это понимаю  как переполнение кэш-памяти на этом PC. Однако стоит перезагрузить на этой РС БД и всё нормализуется.

В общем, наше предприятие использование БД на LO при обработке складских остатков, производства, продаж и пр. - вполне устраивает. Одна бухгалтерия осталась на 1С.

За полгода катастрофических сбоев не было. Бывает рухнет сама LO на какой-то машине, но на внешнюю FB-БД ни разу это не повлияло, вернее не ломало её. Перезапускаешь БД на этой машине и всё снова работает.
Заметил, что проблем с 1С за это время было гораздо больше, чем у моей БД.

К тому же, сделали ежедневное автоархивирование FB-БД, тем более весит она буквально несколько мегабайт - копейки.

В общем - наше предприятие вполне удовлетворено БД на LO.

kompilainenn

Цитата: Kadet от 27 сентября 2019, 21:12В общем - наше предприятие вполне удовлетворено БД на LO.
это не "БД на ЛО", это "использование ЛО, как морды для управления внешней базой FB". А это немного разные штуки.
И ещё, для нормальной работы этого всего нужен специалист, вроде Вас, который не побоится это все делать и грабли чужие разгребать, да ещё и багрепорты слать в ЛО
Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут

mikekaganski

Цитата: kompilainenn от 27 сентября 2019, 21:14И ещё, для нормальной работы этого всего нужен специалист, вроде Вас, который не побоится это все делать и грабли чужие разгребать, да ещё и багрепорты слать в ЛО
Что должно являться нормой на любом предприятии. Неважно, СПО или нет, всегда нужна поддержка. И в случае СПО это обязательно либо кто-то наёмный, либо свой спец. Ни с каким софтом не бывает абсолютно гладко.

В любом случае использовать в масштабе предприятия внутреннюю базу - концептуально неверно. Так что использование внешней базы - главный рабочий режим для Base.
С уважением,
Михаил Каганский

kompilainenn

Цитата: mikekaganski от 27 сентября 2019, 21:33Так что использование внешней базы - главный рабочий режим для Base.
только об этом надо написать в мастере создания внутренней базы крупным шрифтом
Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут

Kadet

Цитата: kompilainenn от 27 сентября 2019, 21:14"использование ЛО, как морды для управления внешней базой FB"
Цитата: mikekaganski от 27 сентября 2019, 21:33В любом случае использовать в масштабе предприятия внутреннюю базу - концептуально неверно. Так что использование внешней базы - главный рабочий режим для Base.
Да, да. Именно так. Полностью согласен. Для серьёзной работы только внешняя БД.
Во-первых - внутренняя БД на ЛО не даёт многопользовательсткого режима (что в своё время меня и сподвигло к выносу внутренней БД вовне).
Во вторых - внешняя БД на порядки надёжней, ибо при любом крушении LO, которая дейтвительно крайне не стабильна сама по себе, внешняя БД не страдает.

Ну, а спец нужен обязательно и по-умолчатию. Это тоже из опыта. По-началу коллеги так просто задалбывают обращениями, пока толком не научатся и не разберутся. Да и в последствии спец должен быть всегда "под рукой"... случаи бывают до парадоксальности...