我使用的是最新的Zeos和SQLite 3。当我们把所有的持久整型字段都设为TLargeInt时,从MySQL转换过来的效果一般都很好。
但是,当我们使用列定义unsigned big int (根据https://www.sqlite.org/datatype3.html,这是唯一允许的无符号类型)时,Delphi将结果字段称为ftWidestring。
发布于 2015-09-21 15:47:34
不,它不会“还原”为字符串,SQlite只是按提供的方式存储数据。
SQLite支持列上的“类型关联”概念。列的类型关联是存储在该列中的数据的推荐类型。这里的重要思想是该类型是推荐的,而不是必需的。任何列仍然可以存储任何类型的数据。只是有些列,如果可以选择,会更喜欢使用一个存储类而不是另一个。列的首选存储类称为它的“亲和性”。
如果您提供/绑定一个文本值,它将存储一个文本值。没有转换到CREATE TABLE语句中提供的类型,因为它可能出现在其他更严格的RBMS中,例如MySQL。
因此,在您的示例中,如果以ftWideString形式检索数据,我猜这是因为您将数据作为文本写入。例如,从MySQL创建SQLite3内容的工具或程序将此列写为文本。
关于数字,在SQLite3中没有“有符号”/“无符号”,也没有精度检查。因此,如果你想存储“无符号大整型”值,只需使用整数,它是Int64。
但是,在所有情况下,即使是SQLite3 API does support UNSIGNED 64 bit integers,Zeos/ZDBC或Delphi也很难支持这种sqlite3_uint64类型(旧版本的Delphi不支持UInt64)。为了确保这一点,您最好将这些值作为文本检索,然后在您的Delphi代码中手动将其转换为UInt64。
更新:
您使用的是Zeos提供的TDataSet后代吗?此组件绑定到DB.Pas,因此需要单个每列类型。这可能是代码混乱的根源(您根本没有显示出来,所以很难弄清楚到底发生了什么)。
最好使用较低级别的ZDBC接口,该接口允许检索每行的列类型,并根据需要调用value getter方法。
发布于 2015-09-28 16:06:49
Zeos使用以下代码(在ZDbcSqLiteUtils.pas中)来确定列的类型:
Result := stString;
...
if StartsWith(TypeName, 'BOOL') then
Result := stBoolean
else if TypeName = 'TINYINT' then
Result := stShort
else if TypeName = 'SMALLINT' then
Result := stShort
else if TypeName = 'MEDIUMINT' then
Result := stInteger
else if TypeName = {$IFDEF UNICODE}RawByteString{$ENDIF}('INTEGER') then
Result := stLong //http://www.sqlite.org/autoinc.html
else if StartsWith(TypeName, {$IFDEF UNICODE}RawByteString{$ENDIF}('INT')) then
Result := stInteger
else if TypeName = 'BIGINT' then
Result := stLong
else if StartsWith(TypeName, 'REAL') then
Result := stDouble
else if StartsWith(TypeName, 'FLOAT') then
Result := stDouble
else if (TypeName = 'NUMERIC') or (TypeName = 'DECIMAL')
or (TypeName = 'NUMBER') then
begin
{ if Decimals = 0 then
Result := stInteger
else} Result := stDouble;
end
else if StartsWith(TypeName, 'DOUB') then
Result := stDouble
else if TypeName = 'MONEY' then
Result := stBigDecimal
else if StartsWith(TypeName, 'CHAR') then
Result := stString
else if TypeName = 'VARCHAR' then
Result := stString
else if TypeName = 'VARBINARY' then
Result := stBytes
else if TypeName = 'BINARY' then
Result := stBytes
else if TypeName = 'DATE' then
Result := stDate
else if TypeName = 'TIME' then
Result := stTime
else if TypeName = 'TIMESTAMP' then
Result := stTimestamp
else if TypeName = 'DATETIME' then
Result := stTimestamp
else if Pos('BLOB', TypeName) > 0 then
Result := stBinaryStream
else if Pos('CLOB', TypeName) > 0 then
Result := stAsciiStream
else if Pos('TEXT', TypeName) > 0 then
Result := stAsciiStream;如果您的表使用任何其他类型名称,或者如果选择输出列不是表列,那么Zeos将回退到stString。对此您无能为力;您必须从string字段中读取值(并希望在与string之间的转换过程中不会丢失任何信息)。
使用其他库可能是一个更好的想法,该库不假定每个数据库都有固定的列类型。
发布于 2015-09-21 23:42:18
最新的Zeos,也就是哪一个?看看它在7.2SVN3642中是否相同:http://svn.code.sf.net/p/zeoslib/code-0/branches/testing-7.2/
米哈尔
https://stackoverflow.com/questions/32689279
复制相似问题