TO_DECIMAL
Introduced or updated: v1.2.959
将一个值转换为 DECIMAL 数据类型。
语法
TO_DECIMAL
( <expr> [, '<format>' ] [, <precision> [, <scale> ] ] )
参数
| 参数 | 说明 |
|---|---|
| expr | 布尔、数字、字符串或变体类型的表达式。 |
| format | 可选。格式化字符串,用于指定十进制结果所需的精度和小数位数,可定义总位数和小数点后的位数。 |
| precision | 可选。结果中有效数字的总位数,默认为 38。 |
| scale | 可选。小数点后的位数,必须不超过精度值,默认为 0。 |
格式说明符 (Format Specifiers)
| 格式说明符 | 说明 | 示例输入 |
|---|---|---|
| '9' | 可选数字(接受数字或无,但在此实现中要求必须有一个) | "123" |
| '0' | 必需数字(在当前实现中与 9 相同) | "123" |
| 'D' | 小数点(接受 '.' 或 ',',始终规范化为 '.') | "12.34" |
| 'G' | 分组(千位)分隔符(在输入中需要 ',') | "1,234" |
| 'S' | 符号('+' 或 '-',作为前缀应用于结果) | "-123" |
| 字面量字符 | 任何字面量字符必须与输入完全匹配 | "NT$123" |
数值转换
当数值转换丢弃小数位时,numeric_cast_option 控制舍入行为:
rounding为默认值。它舍入到最接近的值,恰好在中点时向远离零的方向舍入。truncating向零截断小数位。
FLOAT 和 DOUBLE 输入使用实际存储的精确二进制浮点值。转换会缩放该值,并仅执行一次舍入或截断以得到目标标度。转换不会先将值替换为其最短十进制显示文本。因此,浮点值转换后的数字可能与创建该值时使用的十进制字符串不同。
例如,DOUBLE 1.1 不等于精确的十进制数 1.1。需要保留十进制文本时,请使用十进制字面量或字符串。将已有的 FLOAT 或 DOUBLE 转换为 DECIMAL,无法恢复转换前已经丢失的数字。
SET numeric_cast_option = 'rounding';
SELECT
TO_DECIMAL(1.1::DOUBLE, 38, 18) AS from_float,
TO_DECIMAL('1.1', 38, 18) AS from_text,
TO_DECIMAL((-0.125)::DOUBLE, 18, 2) AS rounded;
-- Expected values: 1.100000000000000089, 1.100000000000000000, -0.13
SET numeric_cast_option = 'truncating';
SELECT TO_DECIMAL((-0.125)::DOUBLE, 18, 2) AS truncated;
-- Expected value: -0.12
UNSET numeric_cast_option;
结果超出目标精度时会报错,包括舍入导致的溢出。NaN、正无穷和负无穷无法转换为 DECIMAL。TRY_CAST 和 TRY_TO_DECIMAL 在转换失败时返回 NULL。VARIANT 内部存储的浮点数也使用相同的二进制值转换规则。
有关算术运算和显式 ROUND 行为,请参阅 Decimal 规则。类型转换设置不会改变这些舍入规则。下方示例使用默认的 rounding 设置。
示例
SELECT TO_DECIMAL('1234.56');
╭───────────────────────╮
│ to_decimal('1234.56') │
├───────────────────────┤
│ 1235 │
╰───────────────────────╯
SELECT TO_DECIMAL('1234.56', '9999D99');
╭──────────────────────────────────╮
│ to_decimal('1234.56', '9999D99') │
├──────────────────────────────────┤
│ 1235 │
╰──────────────────────────────────╯
SELECT TO_DECIMAL('1234.56', 38, 1);
╭──────────────────────────────╮
│ to_decimal('1234.56', 38, 1) │
├──────────────────────────────┤
│ 1234.6 │
╰──────────────────────────────╯
SELECT TO_DECIMAL('NT$1234.56', 'NT$9999D99', 38, 1);
╭───────────────────────────────────────────────╮
│ to_decimal('NT$1234.56', 'NT$9999D99', 38, 1) │
├───────────────────────────────────────────────┤
│ 1234.6 │
╰───────────────────────────────────────────────╯

