【发布时间】:2014-07-03 10:04:21
【问题描述】:
我正在尝试将 Double 和/或 Currency 转换为字符串,以便在 SQL 调用中使用。这意味着我总是对 ThousandSeparator 什么都不是而 DecimalSeparator 是 '.' 感兴趣。
当然,由于我的机器的语言环境配置为丹麦语,Windows 将返回 '.'为ThousandSeparator 和',' 为DecimalSeparator。因此,我需要弥补语言环境错误的可能性。
此外,我的代码需要同时在 D2007(出于遗留原因)和 XE3 中运行。因此,代码如下所示:
{$IF CompilerVersion>=19}
fms := TFormatSettings.Create(LOCALE_SYSTEM_DEFAULT);
{$ELSE}
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, fms);
{$IFEND}
fms.ThousandSeparator := '?';
fms.DecimalSeparator := '.';
Result := FloatToStr(Val, fms);
Result := StringReplace(Result, '?', '', [rfReplaceAll]);
当然,有人可能会争辩说,既然我们假定 FloatToStr 只使用 TFormatSettings' ThousandSeparator 和 DecimalSeparator 使用任何语言环境创建它是没有意义的,因为我们无论如何都会覆盖它们。
不过,我认为这是一个非常简单的操作的大量代码。我也不喜欢ThousandSeparator 是“?”然后被StringReplace() 删除。但由于ThousandSeparator 是char,它实际上不能为空。
我对@987654336@ 和FloatToStrF 进行了一些测试以确保,此时我注意到TFormatSettings.ThousandSeparator 被完全忽略了:
fms := TFormatSettings.Create;
fms.ThousandSeparator := 'W';
fms.DecimalSeparator := '.';
Writeln(FloatToStr(1234567.8901, fms));
Writeln(FloatToStrF(1234567.8901, ffFixed, 18, 4, fms));
我希望每个结果都是“1W234W567.8901”,但它只是“1234567.8901”。所以我想知道这是预期的行为还是奇怪的行为。
因为即使我无法避免TFormatSettings,如果我至少可以忽略ThousandSeparator,我想我会节省两行代码(我想这不是那么重要),但它会是这样做安全吗?我可以一直期望FloatToStr 忽略ThousandSeparator 吗?
【问题讨论】:
-
来自帮助:#0 值表示不应存在千位分隔符,即使格式字符串指定它也是如此。所以如果你用 #0 分配它,那么你总是得到没有千位分隔符的数字。
-
"...用于 SQL 调用..." 您应该改用参数化 SQL 命令并将浮点值作为参数传递。
-
这里你可以看到带有参数的 SQL 查询示例(我只是拿了第一个) - stackoverflow.com/questions/16924629/parameters-in-sql-delphi-7 在这种情况下,你不需要将值转换为字符串,你可以用浮点数分配参数。
-
@Svip:参数化 SQL 语句不是 Delphi 特有的:大多数现有 RDMBS 都支持它们,see 并且应该强制使用它来抑制 SQL 注入攻击。
-
如果您想要独立于区域设置的数字表示,请使用
Str而不是FloatToStr。
标签: delphi