Mysql 当我请求未签名的大整数时,为什么Delphi(Zeos)在SQLite中给我宽字符串字段?
我正在使用SQLite 3的最新Zeos。一旦我们创建了所有的持久整数字段Mysql 当我请求未签名的大整数时,为什么Delphi(Zeos)在SQLite中给我宽字符串字段?,mysql,sql,sqlite,delphi,zeos,Mysql,Sql,Sqlite,Delphi,Zeos,我正在使用SQLite 3的最新Zeos。一旦我们创建了所有的持久整数字段TLargeInt,从MySQL进行转换时,它通常运行良好 但是当我们使用一个列定义unsigned big int(根据允许的唯一无符号类型)时,Delphi将结果字段调用为ftWidestring否,它不会“还原”为字符串,SQlite只存储提供的数据 作为: SQLite支持列上的“类型关联”概念。列的类型关联是存储在该列中的数据的建议类型。这里的重要思想是推荐类型,而不是必需类型。任何列仍然可以存储任何类型的数据。
TLargeInt
,从MySQL进行转换时,它通常运行良好
但是当我们使用一个列定义unsigned big int
(根据允许的唯一无符号类型)时,Delphi将结果字段调用为ftWidestring
否,它不会“还原”为字符串,SQlite只存储提供的数据
作为:
SQLite支持列上的“类型关联”概念。列的类型关联是存储在该列中的数据的建议类型。这里的重要思想是推荐类型,而不是必需类型。任何列仍然可以存储任何类型的数据。只是,如果有选择的话,有些列更喜欢使用一个存储类而不是另一个存储类。列的首选存储类称为“关联”
如果提供/绑定文本值,它将存储文本值。没有转换到CREATE TABLE语句中提供的类型,因为它可能出现在其他更严格的RBM中,例如MySQL
因此,在您的例子中,如果您以ftWideString
的形式检索数据,我想这是因为您以文本的形式编写了数据。例如,从MySQL创建SQLite3内容的工具或程序将此列作为文本编写
关于数字,SQLite3中没有“有符号”/“无符号”,也没有精度检查。所以,如果您想存储“无符号大整数”值,只需使用整数,即Int64
但是,在所有情况下,即使Zeos/ZDBC API或Delphi不支持这种sqlite3_uint64
类型(Delphi的旧版本不支持uint64)。当然,您最好以文本形式检索这些值,然后在Delphi代码中手动将其转换为UInt64
更新:
您是否使用Zeos提供的TDataSet
后代?此组件绑定到DB.Pas
,因此每个列类型需要一个。这可能是代码混乱的根源(您根本没有显示,因此很难弄清楚发生了什么)
您最好使用较低级别的ZDBC接口,该接口允许检索每行的列类型,并根据需要调用value getter方法。否,它不会“还原”为字符串,SQlite只存储提供的数据
作为:
SQLite支持列上的“类型关联”概念。列的类型关联是存储在该列中的数据的建议类型。这里的重要思想是推荐类型,而不是必需类型。任何列仍然可以存储任何类型的数据。只是,如果有选择的话,有些列更喜欢使用一个存储类而不是另一个存储类。列的首选存储类称为“关联”
如果提供/绑定文本值,它将存储文本值。没有转换到CREATE TABLE语句中提供的类型,因为它可能出现在其他更严格的RBM中,例如MySQL
因此,在您的例子中,如果您以ftWideString
的形式检索数据,我想这是因为您以文本的形式编写了数据。例如,从MySQL创建SQLite3内容的工具或程序将此列作为文本编写
关于数字,SQLite3中没有“有符号”/“无符号”,也没有精度检查。所以,如果您想存储“无符号大整数”值,只需使用整数,即Int64
但是,在所有情况下,即使Zeos/ZDBC API或Delphi不支持这种sqlite3_uint64
类型(Delphi的旧版本不支持uint64)。当然,您最好以文本形式检索这些值,然后在Delphi代码中手动将其转换为UInt64
更新:
您是否使用Zeos提供的TDataSet
后代?此组件绑定到DB.Pas
,因此每个列类型需要一个。这可能是代码混乱的根源(您根本没有显示,因此很难弄清楚发生了什么)
您最好使用较低级别的ZDBC接口,该接口允许检索每行的列类型,并根据需要调用value getter方法。最新的Zeos,即哪一个? 查看是否与7.2 svn 3642中的相同:
迈克尔最新的宙斯,就是哪一个? 查看是否与7.2 svn 3642中的相同:
MichalZeos使用以下代码(在
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;
如果您的表使用任何其他类型名称,或者如果SELECT output列不是表列,则Zeos会返回到stString
。
你对此无能为力;您必须从字符串字段读取值(希望转换为字符串和返回不会丢失任何信息)
最好使用其他库,而不是假设每个数据库都有固定的列类型。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;
如果您的表使用任何其他类型名称,或者如果SELECT output列不是表列,则Zeos会返回到stString
。
你对此无能为力;您必须从字符串字段读取值(希望转换为字符串和返回不会丢失任何信息)
最好使用其他库,不要假设每个数据库都有固定的列类型。链接到的页面上的类型名称就是示例,并展示SQLite如何解释类型名称。没有无符号类型。确定,因此当DDL在标准中是正确的,但与SQLite类型不匹配时,它将恢复为字符串作为默认值?SQLite使用动态类型,并且没有列类型。阅读文档!Zeos如何解释类型名称是目前的问题。谢谢!我太习惯了