SQLite有一个有趣的“功能”,让您可以在任何字段中存储任何内容,无论其数据类型如何。
http://www.sqlite.org/different.html#typing
我必须阅读一些由(ab)使用此“功能”创建的外部创建的SQLite文件。它们有一个定义为VARCHAR(30)的字段,但用它来存储最多100个字符或更多的字符串。如果您直接调用SQLite DLL来存储数据,SQLite很乐意这样做而不会进行任何修剪。
我目前正在使用具有SQLite支持的DevArt UniDAC 3.70.0.19来读取这些文件,但是它在定义时非常合理地考虑了字段的大小,因此创建了一个长度为30个字符的TStringField对象。超出此30个字符限制的所有字符都无法访问。
我知道所有可用的SQLite Delphi解决方案,但有人可以告诉我哪些可以处理这个“功能”?
答案 0 :(得分:3)
你可以使用任何直接访问层到sqlite引擎,而不需要任何TDataset层。
例如我们的开源包装器http://blog.synopse.info/post/2011/07/22/SynDBSQLite3%3A-SQLite3-direct-access
实际上,与大多数SQL数据库不同,SQLite不会根据列的声明类型限制可能插入到列中的数据类型。相反,SQLite使用动态类型。声明的列类型仅用于确定列的亲缘关系。没有Db.pas层的直接访问允许使用这个独特的功能。
答案 1 :(得分:0)
因为我想在sqlite3.dll周围使用一个非常薄的包装器,所以我自己写了很多,基于OleVariants:
https://github.com/stijnsanders/TSQLite
它也应该像您所描述的那样“忽略”列类型,因为我没有添加任何其他类型的检查,而不是查询结果提供的类型。
答案 2 :(得分:0)
需要将输出类型改为TEXT
,
使用 CAST
SELECT cast(column as TEXT) FROM `tablename`
答案 3 :(得分:-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不会改变存储格式