Russian Qt Forum

Qt => Базы данных => Тема начата: carlos13 от Октябрь 27, 2009, 20:41



Название: Удаление записей в SQLite, имеющих child records
Отправлено: carlos13 от Октябрь 27, 2009, 20:41
Из таблицы пытаюсь удалить запись (delete from ...) - получаю constraint violation, что есть гуд, т.к. foreign key. Причем удаляю из под программы SQLite Expert 2.2.7 (визуальный тул для администрирования SQLite).

Если пытаюсь удалить ту же запись из своей проги, писаной на Qt (sdk v2009.04), таким макаром:
            QSqlQuery delRn ("delete from kind where nRn = " + id);
            delRn.exec();
то запись удаляется, чего быть НЕ ДОЛЖНО!!!

В чем косяк и как его поправить?


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: carlos13 от Октябрь 27, 2009, 22:20
Ситуация прояснилась. В этой проге используется новый драйвер, поддерживающий foreign key constraints.
Скачал исходники, содержащий файлы с расширением h и c.
Как мне теперь собрать драйвер? Если можно, дайте пошаговую инструкцию - что в какую папку положить, откуда и какие команды выполнить.


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: break от Октябрь 28, 2009, 00:46
Вообще все это весьма странно ведь если вы создали таблицу со вторичным ключом и on deleted = no action или restricted - то вроде как сервер не должен давать удалить соответствующую запись - и без разницы откуда вызывается запрос из Admin-программы или Qt. Причем для SQLite который не клиент-серверный это тоже должно быть верно ведь все равно какая программы делает запрос - всю работу то выполняют библиотеки SQLite.

Цитировать
Ситуация прояснилась. В этой проге используется новый драйвер, поддерживающий foreign key constraints.
А есть ссылка на этот материал? - как Qt драйвер может  поддерживать foreign key если это дело сервера БД, мне кажется драйвер лишь должен получить ответ от сервера, а не проверять вторичные ключи и т.д.


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: carlos13 от Октябрь 28, 2009, 08:41
Тогда выходит, что админский тулз и Qt используют разные версии библиотек SQLite (СУБД ведь не серверная), т.к. возможность некорректно удалить запись имеется.

Мне не хватает знаний на тему, что скачать по ссылке http://www.sqlite.org/releaselog/3_6_19.html и куда это подпихнуть в Qt, чтоб моя прога юзала последнюю версию библиотеки SQLite.

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


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: break от Октябрь 28, 2009, 09:29
Цитировать
Мне не хватает знаний на тему, что скачать по ссылке http://www.sqlite.org/releaselog/3_6_19.html и куда это подпихнуть в Qt, чтоб моя прога юзала последнюю версию библиотеки SQLite.

Попробуй снести все версии SQLite из системы а потом поставить последнюю - и заставить программу работать - я так понимаю SQLite библиотеки под виндой копируются куда - то типа Windows/System32 и драйвер SQLite Qt их оттуда берет во время работы программы.


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 28, 2009, 10:46
carlos13, правильно так и должно быть.
break, Я всегда думал что sqlite никак не относится к ОС и представляет собой файл(ы), в которых собственно и хранится сама База. Qt к этому файлу обращается напрямую. Вот через это src\3rdparty\sqlite.
carlos13, Поэтому изменить возможности связанные с Foreign Key думаю возможны лишь через написание собственного драйвера!


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: break от Октябрь 28, 2009, 11:11
Цитировать
Я всегда думал что sqlite никак не относится к ОС и представляет собой файл(ы), в которых собственно и хранится сама База.

Ну я так не думаю база это база а механизм работы с ней это программа (сервер БД пусть даже супер эмбеддед) - которая лежит в отдельной библиотеке.

Цитировать
Вот через это src\3rdparty\sqlite.
Это и есть исходник библиотеки SQLite который и для винды и для Linux можно скачать в бинарном (скомпиленном) виде, а вот действительно ли Qt использует этот бинарник (компиляет его из src ) или он ей нужен только как набор хедеров я не в курсе. Наверное при сборке Qt есть какие то ключи через которое это управляется.

А не может быть такого что SQLite Expert 2.2.7 сам проверяет FK - и нет никакой путаницы с библиотеками SQLite?


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 28, 2009, 11:31
А не может быть такого что SQLite Expert 2.2.7 сам проверяет FK - и нет никакой путаницы с библиотеками SQLite?
Спрашивается, нафига тогда нужны внешние ключи?
Вот выдержки из документации по SQLite
Код:
This document describes the support for SQL foreign key constraints introduced in SQLite version 3.6.19. 
А вот выдержка из файла sqlite3.h в Qt
Код:
SQLITE_VERSION         "3.5.9"
Да и вообще версия 2.2.7 SQLite Manager вышла 26 октября, а поддержка SQLite-ом Foreign Key появилась только 14 октября. В связи с этим можно сделать вывод, что поддержка внешних ключей будет возможно только в новых версиях Qt.


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: carlos13 от Октябрь 28, 2009, 12:11
Еще раз в хронологическом порядке:
Задача: Нужно было создать базу на SQLite и нарисовать там -тцать табличек.

Для этого скачал прогу SQLite Expert 2.2.6(шесть!) - визуальный тулз для работы с БД.
Создал пустую базу. Это, условно говоря, обыкновенный файл. Роль СУБД, насколько понимаю играет SQL Library - sqllite3.dll. В программе она версии 3.6.18(восемнадцать). Именно эта dll позволяет работать с файлом и манипулировать данными и ограничена эта возможность функциональностью ЭТОЙ версии dll. В этой версии dll - форин кеи НЕ ПОДДЕРЖИВАЛИСЬ! И я реализовал структуру БД без них, но закладывая в голове их реализацию на Qt/с++.

Когда на сайте SQLite увидел, что вышла новая sqllite3.dll 3.6.19(девятнадцать) и она позволяет реализовывать форин кеи, - зашел на сайт SQLite Expert и скачал обновленную прогу версии 2.2.7(семь!). Обновление состояла именно в том, что SQLite Expert использовала новую dll и появилось несколько окошек для визуального создания этих форин кеев, чем я незамедлительно воспользовался. Всё.

Дальше выяснил, саму проблему - ёё уже описал.

Предполагаю, что и Qt использует sqllite3.dll в том или ином виде, но на момент выхода QT-шного релиза в этой dll НЕ ПОДДЕРЖИВАЛИСЬ форин кеи.

T.к. в Qt я ноль, прошу помощи в следующем:
 Есть исходные данные по sqllite3.dll 3.6.19(девятнадцать) - http://www.sqlite.org/releaselog/3_6_19.html
 И мне надо сделать, что бы Qt работала именно с этой версией библиотеки. Как это сделать?!


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 28, 2009, 12:17
Написать свой драйвер QT, использующий sqllite3.dll 3.6.19(девятнадцать)


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: break от Октябрь 28, 2009, 15:12
Цитировать
Написать свой драйвер QT, использующий sqllite3.dll 3.6.19(девятнадцать)
А если попробовать просто перекомпилировать с ней?


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 28, 2009, 17:56
Попробовать можно и в приниципе даже должно получиться... Но это будет нарушением лицензии. Хотя, сейчас в Qt самопальные исправления многие делают.


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: carlos13 от Октябрь 29, 2009, 08:27
BaltikS, а что для этого сделать надо, распиши пожалуйста, я попробую, мне однако надо )


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 10:40
Я SqlLite не собирал сам, но полагаю если скачать исходники и поместить в папку src\3rdparty\sqlite, заменив существующие, и пересобрать драйвер SQLITE, то теоретически должно заработать


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: DmP от Октябрь 29, 2009, 12:10
С сайта sqlite.org надо скачать sqlite-amalgamation.
И заодно глянуть на файлик в Qt src\3rdparty\patches\sqlite-3.5.6-config.patch, может пригодится.


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 15:36
-system-sqlite ..... Use sqlite from the operating system


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 15:42
Это что такое?


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 15:58
Код:
configure -help

нужно собрать qt с этим ключом..... тогда qt будет использовать sqlite из системы.....


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 16:02
crossly, я такого у себя не вижу... И вообще к чему это?


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 16:04
Код:
-no-sql-<driver> ... Disable SQL <driver> entirely.
    -qt-sql-<driver> ... Enable a SQL <driver> in the QtSql library, by default
                         none are turned on.                                   
    -plugin-sql-<driver> Enable SQL <driver> as a plugin to be linked to       
                         at run time.                                         

                         Possible values for <driver>:
                         [  db2 ibase mysql oci odbc psql sqlite sqlite2 sqlite_symbian tds ]

    -system-sqlite ..... Use sqlite from the operating system.


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 16:05
Пардон, увидел. Не понял к чему твой ответ...


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 16:10
к тому что у автора топика различаются версии sqlite.... используемые qt и утилитой администрирования.... сборка с этим ключом дает возможность использовать одну версию sqlite


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 16:12
crossly, если ты был бы очень внимателен в прочтении постов, ты бы так не писал... Ты ошибаешься!


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 16:37
Тогда выходит, что админский тулз и Qt используют разные версии библиотек SQLite (СУБД ведь не серверная), т.к. возможность некорректно удалить запись имеется.

Мне не хватает знаний на тему, что скачать по ссылке http://www.sqlite.org/releaselog/3_6_19.html и куда это подпихнуть в Qt, чтоб моя прога юзала последнюю версию библиотеки SQLite.

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

в чем я не прав??


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 16:39
В том, что  SQLite Expert, юзает DLL для работы с SQLite и это к системе не имеет ни какого отношения!!!


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 16:40
В том, что  SQLite Expert, юзает DLL для работы с SQLite и это к системе не имеет ни какого отношения!!!
какую DLL??


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 16:45
SQLite эксперт использует sqlite3.dll. Теперь, кто это сказал что SQLite в системе? Для того чтобы он был в системе нужно как минимум был h-nik для компиляции драйвера Qt. Теперь ткни пальцем, где в системе есть SDK SQLite-а? Одной DLL увы недостаточно!


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 16:50
SQLite эксперт использует sqlite3.dll. Теперь, кто это сказал что SQLite в системе? Для того чтобы он был в системе нужно как минимум был h-nik для компиляции драйвера Qt. Теперь ткни пальцем, где в системе есть SDK SQLite-а? Одной DLL увы недостаточно!
суть моего поста сводилась к тому чтобы qt и sqlite expert использовали одну и туже версию dll..... ну а на счет sdk .... :).... товарищи.... вы тут программирование занимаетесь или чем.... ?? качаем исходники ....собираем.... и получаем...


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 16:51
crossly, ты видимо не в курсах, но Qt не использует DLL SQLite.
Так вот, суть твоего поста - разведённый флуд!


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 16:54
crossly, ты видимо не в курсах, но Qt не использует DLL SQLite.
Так вот, суть твоего поста - разведённый флуд!

если ты не в курсе.... и отказываешься читать документацию.... ещё раз повторюсь.... ключ --system-sqlite для того и предназначен что бы qt не компилировала src/3rdparty/sqlite.... а использовала sqlite3.dll


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 17:01
Да, я не в курсе был про -system-sqlite ... Теперь:
1) если ты такой умный и прочёл всю документацию, то покажи мне где это написано? В Assistant я не нашёл.
2) читаем внимаетельно вопросы и ответы. Вопрос был как сделать? Твой ответ
Код:
system-sqlite ..... Use sqlite from the operating system
вообще не понятно о чём был.
3) Использование sqlite3.dll невозможно без SDK. В системе sqlite3.dll - нет! Есть только в программе SQLite Expert. Следовательно твой ответ вообще не по существу.
4) Телепатов здесь нет.


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 17:30
лан.... раз пошла такая пьянка....
на примере винды.... (у линуксоидов таких проблем обычно не возникает :))...
качаем исходники sqlite ....
компилируем ( у кого трудности... есть манул на офсайте)...
получаем *.lib,*.dll...
ложим *.lib в %LIBS%..... *.dll в %PATH%.... *.h в %INCLUDE%..... (сие же можно и без копирования.... просто при конфигурировании qt указать -I и -L)

собираем qt с ключом --system-sqlite.... в итоге qt будет использовать dll лежащую у вас в %PATH%.....

в чем плюс сего ?.... в том что всегда модно иметь свежую sqlite без пересборки самой qt....


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 17:42
главное понять .... что есть sdk :).... это по сути дела всего лишь набор либов и хидеров..... и любой сдк можно собрать своими "ровными" руками... :)


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: BaltikS от Октябрь 29, 2009, 17:47
Всё равно пересобирать нужно будет SQLite тогда, точнее его библ-ку (особенно для линуксоидов). Поэтому особой разницы в трудоёмкости не вижу. К тому же на существующие приложения (его использующие) это вряд ли повлеяет.

crossly, просто я первоначально твой ответ не понял. Собрать SQLite, который в системе....но его нет в системе, в винде(вопрос про винду был) его нужно всегда ставить...


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: crossly от Октябрь 29, 2009, 17:51
Всё равно пересобирать нужно будет SQLite тогда, точнее его библ-ку (особенно для линуксоидов). Поэтому особой разницы в трудоёмкости не вижу. К тому же на существующие приложения (его использующие) это вряд ли повлеяет.
ну :) .... пересобрать sqlite гораздо проще и быстрее чем qt..... да собственно вопрос по моему был не в этом.....


Название: Re: Удаление записей в SQLite, имеющих child records
Отправлено: carlos13 от Ноябрь 01, 2009, 02:14
Так, продолжаем, но в русле темы!

По совету  BaltikS скачал исходники, которые amalgamation; поместил в папку src\3rdparty\sqlite, заменив существующие, и пересобрал драйвер SQLITE:
   cd ...\qt\src\plugins\sqldrivers\sqlite   
   qmake sqlite.pro
   mingw32-make.exe
получив собственно говоря qsqlited4.dll и libqsqlited4.a. Скопировал их в папку драйверов (...plugins\sqldrivers).

Не помогло. Проблема, к сожалению, осталась. Может есть у кого еще идеи.

PS. Заодно прочитал, что lower(X)    Return a copy of string X with all ASCII characters converted to lower case. The default built-in lower() function works for ASCII characters only. To do case conversions on non-ASCII characters, load the ICU extension. Так что еще один гемор, но уже с регистронезависимым поиском. Так что SQLite прекрасна!!! Вот думаю, не мигрировать ли на FireBird, а то зима на носу.