Страница 3 из 3
Re: Класс-обёртка для SQLite
Добавлено: 13.05.2011 16:07:18
Vadim
Nik писал(а):Я, увы, не знаю такого
Я тоже.
Может просто в цикле сохранять данные в текстовом файле, а потом, так же циклом, считывать?
Re: Класс-обёртка для SQLite
Добавлено: 13.05.2011 16:55:29
Nik
Vadim писал(а):Nik писал(а):Я, увы, не знаю такого
Я тоже.
Может просто в цикле сохранять данные в текстовом файле, а потом, так же циклом, считывать?
Сейчас как раз такой вариант пробую реализовать. С файловым потоком какой-то больно мутный алгоритм получается.
Re: Класс-обёртка для SQLite
Добавлено: 13.05.2011 19:11:42
Vadim
Nik
Можно без потока, обычным паскалевским способом - AssignFile(), Rewrite(), WriteLn()...
Re: Класс-обёртка для SQLite
Добавлено: 13.05.2011 23:22:07
Padre_Mortius
Результаты запроса лежат в таблице TSQLiteTable. Требуется каким-то образом сохранить эти результаты в файл, а затем загрузить их из файла в другой TSQLiteTable.
TSQLiteTable принадлежат одной базе или разным? Выгрузка в файл обязательна?
Re: Класс-обёртка для SQLite
Добавлено: 14.05.2011 10:46:30
Nik
2Padre_Mortius
Они на разных машинах в разных базах. Не обязательно в файл, можно в поток.
Re: Класс-обёртка для SQLite
Добавлено: 14.05.2011 17:03:30
Padre_Mortius
а чем не устроил текст с разделителями? вроде бы самое универсальное решение. На его основе уже как хотите так и реализуйте... Хоть поток, хоть файл...
Re: Класс-обёртка для SQLite
Добавлено: 14.05.2011 19:16:08
Nik
Padre_Mortius писал(а):а чем не устроил текст с разделителями? вроде бы самое универсальное решение. На его основе уже как хотите так и реализуйте... Хоть поток, хоть файл...
Там свои нюансы. Сохранить в текстовый файл - дело плёвое, но вот обратно в TSQLiteTable правильно развернуть текст пока не получается.
Re: Класс-обёртка для SQLite
Добавлено: 14.05.2011 22:11:05
Padre_Mortius
Сложности могут возникнуть только если необходимо исключить импорт повторных записей, или если запись найдена и ее необходимо обновить.
Re: Класс-обёртка для SQLite
Добавлено: 14.05.2011 23:01:26
Nik
В данный момент косяк вот в чём. TSQLiteTable хранит данные в виде массива указателей TList. Указатели разных типов. Проблема в том, что если данные сохранять в текстовый файл (штатные методы TSQLiteTable это позволяют через финт ушами), то потом не удаётся в точности восстановить исходный TList, поскольку типы указателей теряются.
Пока пришёл вот к чему. Самым оптимальным способом было бы сохранение данных из TList в том виде, в каком они есть, в TMemoryStream, не приводя их к текстовому виду. Затем, соответственно, всё считать из потока (который можно и через сохранение файл куда-то передать, и по сети без сохранения) и записать в TList.
Разобрать TList на элементы не проблема (свойство Items есть), собрать - тоже. Затык в запись указателей в поток. Я пробовал в лоб:
Код: Выделить всё
fResults: TList;
...
res: TMemoryStream;
...
res.Write(fResults[i]^, SizeOf(fResults[i]));
Но при таком раскладе в потоке оказывается ерунда (что предсказуемо). Если писать fResults[i] - в поток попадают (если я правильно понял) адреса.
Кто-нибудь знает, как корректно записать Pointer неизвестного типа в поток и потом их обратно считать?
Re: Класс-обёртка для SQLite
Добавлено: 15.05.2011 14:04:35
Odyssey
Ветка о сохранении списка указателей в поток - тут:
viewtopic.php?t=7045А вообще, можно всё то же самое сделать средствами SQL:
http://www.sqlite.org/lang_createtable.htmlИскать по "CREATE TABLE ... AS SELECT"
причём можно сохранить новую таблицу даже в новую отдельную базу данных, подключенную через ATTACH DATABASE (
http://www.sqlite.org/lang_attach.html). И тогда полученный файл базы можно пересылать и вливать в другую базу через
INSERT INTO ... SELECT FROM ...
http://www.sqlite.org/lang_insert.htmlИскать по "The second form of the INSERT statement"
Re: Класс-обёртка для SQLite
Добавлено: 15.05.2011 16:22:33
Nik
2
Odyssey Спасибо за наводку! Пожалуй, через временную ДБ будет проще реализовать. Буду копать в эту сторону. Собственно, уже разобрался, как подключить временную ДБ, осталось как-то в неё перенести результаты выборки.
Добавлено спустя 44 минуты 32 секунды:Никак не получается записать что-либо во временную БД. Выполняю такой код:
Код: Выделить всё
SQL_db.ExecSQL('ATTACH ''c:temp.db3'' AS tmp_db');
if not (SQL_db.TableExists('tmp_table')) then
begin
SQL_query:='CREATE TABLE IF NOT EXISTS [tmp_table] ([id] INTEGER, [name] CHAR, [parent] INTEGER, [cat_order] INTEGER)';
SQL_db.execsql(SQL_query);
SQL_db.ExecSQL('INSERT INTO tmp_table (id, name, parent, cat_order) VALUES ("0", "Тестовая категория", "-1", "0")');
end;
Файл новой БД создаётся, но какие бы команды не выполнялись, его размер остаётся 0 байт. Пробовал и явно обращаться к таблицам (
tmp_db.tmp_table) и просто по имени (судя по описанию на сайте SQLite при отсутствии в основной и временной БД одноимённых таблиц можно обращаться к таблицам просто по имени - без префикса). Отрабатывает только код создания таблиц - но таблицы создаются в основной БД (даже при явном задании префикса с именем временной БД - в этом случае в основной ДБ создаются таблицы с именем типа
tmp_db.tmp_table, включающим и префикс тоже).
Добавлено спустя 33 минуты 23 секунды:Всё, кажется разобрался. В итоге получилось вот что:
Код: Выделить всё
// Цепляем временную БД
SQL_db.ExecSQL('ATTACH "c:send.db3" AS xdb');
// Делаем выборку из основной БД и сохраняем её во временную
SQL_query:='CREATE TABLE [xdb].[myres] AS SELECT * FROM rashod WHERE bill=1';
SQL_db.execsql(SQL_query);
2
Odyssey: ещё раз спасибо
Добавлено спустя 12 минут 52 секунды:PS. Уже просто из спортивного интереса подумал: как бы сделать всё то же самое без сохранения файла на диск? SQLite позволяет создавать БД в памяти, но до такой БД вряд ли удастся добраться с целью сохранения в TMemoryStream.