5

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 解决方案,但是有人可以告诉我其中哪些可以处理这个“功能”吗?

4

4 回答 4

3

您可以使用任何直接访问 sqlite 引擎的层来执行此操作,而无需任何 TDataset 层。

例如我们的开源包装http://blog.synopse.info/post/2011/07/22/SynDBSQLite3%3A-SQLite3-direct-access

事实上,与大多数 SQL 数据库不同,SQLite 不会根据列的声明类型来限制可以插入到列中的数据类型。相反,SQLite 使用动态类型。列的声明类型仅用于确定列的亲和性。无需 Db.pas 层的直接访问允许使用此独特功能。

于 2012-12-18T06:15:00.467 回答
0

您的解决方案可以放在 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 的转换不会改变存储格式

于 2012-12-18T21:03:47.913 回答
0

因为我想要一个非常薄的 sqlite3.dll 包装器,所以我编写了自己的,主要基于 OleVariants:

https://github.com/stijnsanders/TSQLite

它还应该像您描述的那样“忽略”列类型,因为除了查询结果提供的内容之外,我没有添加其他类型检查。

于 2012-12-19T11:58:44.263 回答
0

需要将输出类型更改为TEXT,使用CAST

SELECT cast(column as TEXT) FROM `tablename`
于 2021-04-06T15:04:37.527 回答