2012-12-18 6 views
4

У SQLite есть интересная «функция», позволяющая хранить что-либо в любом поле независимо от его типа данных.Поддержка Delphi для набора символов SQLite

http://www.sqlite.org/different.html#typing

мне приходится читать некоторые внешне созданные SQLite файлы, которые были созданы (AB), используя эту «особенность». Они имеют поле, определенное как VARCHAR (30), но используют его для хранения строк до 100 символов или более. SQLite с радостью делает это без каких-либо обрезки, если вы делаете прямые вызовы в SQLite DLL для хранения ваших данных.

В настоящее время я использую DevArt UniDAC 3.70.0.19, который имеет поддержку SQLite для чтения этих файлов, однако он довольно разумно уважает размер поля, поскольку он определен, и поэтому создает объект TStringField длиной 30 символов. Все символы, хранящиеся за пределами этого предела в 30 символов, недоступны для меня.

Я знаю обо всех доступных решениях Delphi для SQLite, однако может кто-нибудь сказать мне, кто из них, если кто-нибудь может справиться с этой «функцией»?

ответ

3

Вы можете сделать это с помощью любого слоя прямого доступа к серверу sqlite без слоя TDataset.

Например наш открытый исходный код обертки http://blog.synopse.info/post/2011/07/22/SynDBSQLite3%3A-SQLite3-direct-access

В самом деле, в отличие от большинства баз данных SQL, SQLite не ограничивает тип данных, которые могут быть вставлены в столбец на основе объявленного типа столбца. Вместо этого SQLite использует динамическую типизацию. Объявленный тип столбца используется для определения близости только столбца. Прямой доступ без слоя Db.pas позволяет использовать эту уникальную функцию.

-1

Ваше решение может лежать в sqlite. Схема по умолчанию недоступна для записи (вы не можете ОБНОВИТЬ таблицу sqlite_master), но с разумным знанием и небольшой помощью PRAGMA writable_schema = ON; вы можете это сделать. Таким образом, некоторые изменения безопасны, например, изменение VARCHAR (N) на VARCHAR (M), sqlite не заботится о числе в скобках.

Шаг 1, ваша схема не должна превышать 30 символов

CREATE TABLE [TestTable] (
[Id] INTEGER PRIMARY KEY AUTOINCREMENT, 
[Txt] VARCHAR(30) 
) 

Строка ниже позволяет sqlite_table изменения

PRAGMA writable_schema=ON; 

И следующее утверждение изменит пределы 100

Update sqlite_master set sql='CREATE TABLE [TestTable] (
[Id] INTEGER PRIMARY KEY AUTOINCREMENT, 
[Txt] VARCHAR(100) 
)' where tbl_name='TestTable' and type='table' 

Но вы должны знать, что делаете, так как некоторые изменения не приветствуются, потому что sqlite ожидает некоторый формат хранения на основе информации в схеме. Varchar для преобразования VARCHAR не изменяет формат хранения

+0

Это не имеет никакого смысла в sqlite.В отличие от большинства баз данных SQL, SQLite не ограничивает тип данных, которые могут быть вставлены в столбец на основе объявленного типа столбцов. Вместо этого SQLite использует динамическую типизацию. Объявленный тип столбца используется для определения близости только столбца. Например, такие трюки для подделки определения таблицы не будут работать, например, с запросами sql. –

+0

@Arnaud_Bouchez, OP quote: «Все символы, хранящиеся за пределами этого предела в 30 символов, недоступны для меня». Этот трюк решил именно эту проблему, так как код, который анализирует sqlite-схему (единственный способ сделать ограниченную по размеру типизацию), теперь будет более чем счастлив показать все символы ниже 100 – Maksee

+0

. В заголовке вопроса явно указано «Поддержка Delphi для набора символов SQLite », а усечение - лишь небольшая часть проблемы. Блоки SQLite3 на основе TDataSet (такие как UniDac или даже самый последний драйвер DBExpress, поставляемый с XE3) просто не смогут использовать эту функцию. Вопрос OP заключается в использовании этой функции в Delphi, а не только для исправления усечения текстового поля. Проблема не в SQLite3, а на стороне Delphi обрабатываются API-интерфейсы SQlite3 и возвращаются данные. Вот почему ваш ответ верен, но, к сожалению, выходит за рамки. –

0

Потому что я хотел действительно тонкую оболочку вокруг sqlite3.dll, я написал сам, в значительной степени основаны на OleVariants:

https://github.com/stijnsanders/TSQLite

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

+0

Зачем использовать оварианты, а не варианты? Сохранение BSTR для текста довольно медленно. Но хорошая обертка. –

+0

Хороший вопрос, я всегда использовал OleVariants, потому что узнал их через COM/ActiveX. –