【问题标题】:SQL Server CONVERT(NUMERIC(18,0), '') fails but CONVERT(INT, '') succeeds?SQL Server CONVERT(NUMERIC(18,0), '') 失败但 CONVERT(INT, '') 成功?
【发布时间】:2010-12-21 01:43:00
【问题描述】:

PRINT CONVERT(NUMERIC(18,0), '')

产生Error converting data type varchar to numeric.

然而,

PRINT CONVERT(INT, '')

生成0 没有错误...

问题:是否有一些 SQL Server 标志,或者我需要为每个 varchar 到数字的转换做 case 语句? (除了显而易见的原因?)

【问题讨论】:

  • 我不认为它不可靠,它只是不是一个完整的测试。它表示该值成功转换为其中一种数字类型,因此我添加了条件来测试至少一个数字、没有美元符号、没有科学记数法等。
  • 你怎么知道它不可靠?你必须。当shown different (and working) techniques 使用派生表和 CASE 时,您说您不想依赖它们。如果其他人读到这篇文章,请投反对票。
  • case when @a not like '%[^0-9.]%' 非常接近但没有 isumeric(),它会接受像 '123.45.67' 之类的东西

标签: sql sql-server numeric-conversion


【解决方案1】:

使用ISNUMERIC

declare @a varchar(20)
set @a = 'notanumber'
select case when isnumeric(@a) = 0 then 0 else convert(numeric(18,0),@a) end

【讨论】:

  • 我想我可以重构并将所有这些问题放在内联函数中。 select 语句中的 case 语句唯一不好的地方是使 select 语句长达三页。
  • 上述不适用于所有输入字符串,例如尝试@a='-' 或@a='$'。请参阅我的回答中引用的文章。
【解决方案2】:

ISNUMERIC 并不总是像您预期的那样工作:特别是对于一些随后无法转换为数字的值,它会返回 True。

This article 描述了该问题并建议如何使用 UDF 解决该问题。

【讨论】:

    【解决方案3】:

    对于 float 和 int 类型,空字符串将转换为零,但不会转换为十进制。 (并转换为 1900 年 1 月 1 日,因为日期时间 = 零)。我不知道为什么......它只是......

    如果您需要小数(18,0),请改用 bigint。或者先通过浮动投射

    ISNUMERIC 将接受 -.1.2E3 作为数字,但都无法转换为十进制。

    【讨论】:

    • 我的问题需要更好的措辞。我的意思是问如何可靠地测试字符串中的数字。我看到你有充分的理由不喜欢 isnumeric,但我不明白如何将它转换为 bigint 或 float 会确定它是一个没有错误的有效数字。据我了解,将字符串转换为 bigint 会产生不正确的零值或脚本失败。无论如何,铸造浮动似乎总是失败。
    • 除了not myField like '%[^0-9]%' and LEN(myField) < 9 之外,我还没有看到没有 isumeric 的方法(但这不适用于十进制。)但是,做 isumeric() 而不是(检查事情它错过了)对我有用(我在答案中对此进行了评论)因此我标记了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    相关资源
    最近更新 更多