【问题标题】:CAST nvarchar to int when ISNUMERIC equal 1当 ISNUMERIC 等于 1 时将 nvarchar 转换为 int
【发布时间】:2015-03-26 21:53:04
【问题描述】:

我有带有varchar 列的表格。 我需要做的是选择在此列中具有数值但值在 100 和 150 之间的所有行 下面是一些数据的示例代码:

create table test (number nvarchar(10))

insert into test (number) values ('100'), ('140'), ('222ass'), ('2'), ('some text')

想到的第一个想法:

select * from test where isnumeric(number) = 1 and cast(number as int) between 100 and 150

但是错误:

Conversion failed when converting the nvarchar value 'some text' to data type int.

注意:当字段为 varchar - 此代码工作正常。

下次试试。我使用子查询。为什么?我认为在子查询中我将有正确的值(条件ISNUMERIC 在子查询中)并且我可以毫无问题地进行强制转换:

select 
  number
from (
  SELECT 
    number
  FROM test 
  where isnumeric(number) = 1) ds 
where number between 100 and 150

但也有ERROR(同上)

在这个错误之后,我抓住了最后的希望(当前的思维方式)。我添加了第三个子查询:)

select * 
from (
  select 
    cast(number as int) n 
  from (
    SELECT 
      number
    FROM test 
    where isnumeric(number) = 1) ds 
) ds2
where n between 100 and 150

但又出现错误:(

知道如何解决我的问题吗? 我也很高兴知道为什么会出现此错误。为什么 MSSQL 不想转换我的数据?

感谢您的帮助!

PS。 MSSQL 2008 R2

【问题讨论】:

  • 您无法控制 where 子句中谓词的处理顺序。要短路,您必须使用查询/cte 首先隔离 isumeric = 1 的行。然后您可以进行第二次查询以检查范围。在这里要小心...isnumeric 并不意味着该值可以转换为 int。该功能允许很多东西通过。
  • 我做到了。在第二个和第三个例子中。首先,我隔离 ISNUMERIC = 1 的行(这是新数据集)接下来我从中选择。但是还是报错

标签: sql-server casting type-conversion


【解决方案1】:

你可以像这样使用CASE

SELECT number
FROM (
  SELECT CASE WHEN isnumeric(number) = 1 THEN number
              ELSE CAST (NULL AS int)
         END AS number         
  FROM test) t
WHERE number BETWEEN 100 and 150

【讨论】:

  • 不错!你能解释一下为什么我需要用例吗?在我的示例中,我的子查询被“过滤”并且只有正确的值。但是 MSSQL 说我没有数值。这不是真的
  • SQL Server 不会像编程语言那样从左到右评估 WHERE 子句。它通过一个优化器运行它并重新评估该语句以对查询计划最优化。但是,CASE 语句并未以这种方式进行优化,而是从左到右处理。
  • 感谢您的帮助和@Brandon 感谢您的解释!
【解决方案2】:

如果您使用 SQL Server 2012 或更高版本,TRY_CONVERT 将解决您的问题:

TRY_CONVERT(int, number)

返回 number 转换为 int(如果可以进行此类转换),否则返回 NULL

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多