TSQL-替换为isnumeric=0

TSQL-替换为isnumeric=0,tsql,sql-server-2016,isnumeric,Tsql,Sql Server 2016,Isnumeric,我有一个select语句,在该select语句中有几个列,我在这些列上执行基本计算(例如[Col1]*3.14)。但是,有时我会遇到非数值,当这种情况发生时,整个存储过程由于一行而失败 我曾考虑过使用一个,其中ISNUMERIC(Col1)0,但是我会排除其他列中的信息 TSQL中有没有一种方法可以用NULL或0替换所有Sting??类似于 SELECT blah1, blah2, blah3 CASE WHEN ISNUMERIC(Col1) = 1 THEN [Col1] * 3.14

我有一个select语句,在该select语句中有几个列,我在这些列上执行基本计算(例如[Col1]*3.14)。但是,有时我会遇到非数值,当这种情况发生时,整个存储过程由于一行而失败

我曾考虑过使用一个
,其中ISNUMERIC(Col1)0
,但是我会排除其他列中的信息

TSQL中有没有一种方法可以用NULL或0替换所有Sting??

类似于

SELECT blah1, blah2, blah3
   CASE WHEN ISNUMERIC(Col1) = 1 THEN [Col1] * 3.14 ELSE NULL END as whatever
FROM your_table
也可以提出这样一个例子:

  • 非数值应转换为数值或空值(如果该列中预期为空),并且
  • 如果需要数字,那么列首先应该是数字数据类型,而不是字符数据类型,这允许出现这些类型的错误
      类似于

      SELECT blah1, blah2, blah3
         CASE WHEN ISNUMERIC(Col1) = 1 THEN [Col1] * 3.14 ELSE NULL END as whatever
      FROM your_table
      
      也可以提出这样一个例子:

      • 非数值应转换为数值或空值(如果该列中预期为空),并且
      • 如果需要数字,那么列首先应该是数字数据类型,而不是字符数据类型,这允许出现这些类型的错误
      ISNUMERIC
      是一种可怕的方法,因为有太多的东西标识为
      NUMERIC
      ,它们不能与非
      货币
      数据类型相乘

      这失败得很惨,因为“-”是一个数字

      DECLARE @example TABLE (numerics VARCHAR(10));
      
      INSERT INTO @example VALUES ('-')
      
      SELECT CASE WHEN ISNUMERIC(numerics) = 1 THEN numerics  * 3.14 ELSE NULL END  
      FROM @example;
      
      请尝试使用
      Try_CAST
      (尽管可以根据需要修改小数精度):


      ISNUMERIC
      是一种可怕的方法,因为有太多的东西被标识为
      NUMERIC
      ,它们不能被非
      货币
      数据类型相乘

      这失败得很惨,因为“-”是一个数字

      DECLARE @example TABLE (numerics VARCHAR(10));
      
      INSERT INTO @example VALUES ('-')
      
      SELECT CASE WHEN ISNUMERIC(numerics) = 1 THEN numerics  * 3.14 ELSE NULL END  
      FROM @example;
      
      请尝试使用
      Try_CAST
      (尽管可以根据需要修改小数精度):

      我更喜欢试演:

      SELECT
          someValue
          ,TRY_CAST(someValue as int) * 3.14     AS TRY_CAST_to_int
          ,TRY_CAST(someValue as decimal) * 3.14 AS TRY_CAST_to_decimal
          ,IIF(ISNUMERIC(someValue) = 1, someValue, null) * 3.14 as IIF_IS_NUMERIC
      FROM (values 
          ( 'asdf'), 
          ( '2' ),
          ( '1.55')
      ) s(someValue)
      
      我更喜欢试演:

      SELECT
          someValue
          ,TRY_CAST(someValue as int) * 3.14     AS TRY_CAST_to_int
          ,TRY_CAST(someValue as decimal) * 3.14 AS TRY_CAST_to_decimal
          ,IIF(ISNUMERIC(someValue) = 1, someValue, null) * 3.14 as IIF_IS_NUMERIC
      FROM (values 
          ( 'asdf'), 
          ( '2' ),
          ( '1.55')
      ) s(someValue)
      

      trycast将测试特定类型

      declare @T table (num varchar(20));
      insert into @T values ('12'), ('3.14'), ('5.6E12'), ('$120'), ('-'), (''), ('cc'), ('aa'), ('bb'), ('1/5'); 
      select t.num, ISNUMERIC(t.num) as isnumeric
           , isnull(TRY_CONVERT(smallmoney, t.num), 0) as smallmoney 
           , TRY_CONVERT(float, t.num) as float
           , TRY_CONVERT(decimal(18,4), t.num) as decimal 
           , isnull(TRY_CONVERT(smallmoney, t.num), TRY_CONVERT(float, t.num)) as mix
      from @T t
      
      num                  isnumeric   smallmoney            float                  decimal
      -------------------- ----------- --------------------- ---------------------- ---------------------------------------
      12                   1           12.00                 12                     12.0000
      3.14                 1           3.14                  3.14                   3.1400
      5.6E12               1           0.00                  5600000000000          NULL
      $120                 1           120.00                NULL                   NULL
      -                    1           0.00                  NULL                   NULL
                           0           0.00                  0                      NULL
      cc                   0           0.00                  NULL                   NULL
      aa                   0           0.00                  NULL                   NULL
      bb                   0           0.00                  NULL                   NULL
      1/5                  0           0.00                  NULL                   NULL
      

      有趣的是,最后一个仍然失败。trycast将测试特定类型

      declare @T table (num varchar(20));
      insert into @T values ('12'), ('3.14'), ('5.6E12'), ('$120'), ('-'), (''), ('cc'), ('aa'), ('bb'), ('1/5'); 
      select t.num, ISNUMERIC(t.num) as isnumeric
           , isnull(TRY_CONVERT(smallmoney, t.num), 0) as smallmoney 
           , TRY_CONVERT(float, t.num) as float
           , TRY_CONVERT(decimal(18,4), t.num) as decimal 
           , isnull(TRY_CONVERT(smallmoney, t.num), TRY_CONVERT(float, t.num)) as mix
      from @T t
      
      num                  isnumeric   smallmoney            float                  decimal
      -------------------- ----------- --------------------- ---------------------- ---------------------------------------
      12                   1           12.00                 12                     12.0000
      3.14                 1           3.14                  3.14                   3.1400
      5.6E12               1           0.00                  5600000000000          NULL
      $120                 1           120.00                NULL                   NULL
      -                    1           0.00                  NULL                   NULL
                           0           0.00                  0                      NULL
      cc                   0           0.00                  NULL                   NULL
      aa                   0           0.00                  NULL                   NULL
      bb                   0           0.00                  NULL                   NULL
      1/5                  0           0.00                  NULL                   NULL
      

      有趣的是,最后一个仍然失败

      通过使用TRY_CAST()而不是ISNUMERIC(),省去了一些可能的麻烦。
      ISNUMERIC
      回答了一个没有人想要答案的问题—“这个字符串是否可以转换为至少一种数字数据类型,我不在乎具体是哪种?”。太好了。事实上,您需要一个
      decimal
      ,并且字符串只能转换为
      money
      类型,这确实让您向前迈进了一步……使用TRY\u CAST()而不是ISNUMERIC(),省去了一些可能的麻烦。
      ISNUMERIC
      回答了没有人想要答案的问题-“这个字符串是否可以转换为至少一种数字数据类型,我不在乎具体是哪种类型?”。那么,太好了。事实上,您需要一个
      十进制
      ,并且字符串只能转换为
      货币
      类型,这确实让您向前迈进了一步…
      插入到您的_表(blah1、blah2、blah3、Col1)值中(1,2,3,$4.0')
      试试这个,你仍然会得到一个错误-
      的一个糟糕例子是数值
      插入你的_表(blah1,blah2,blah3,Col1)值(1,2,3,$4.0')
      试试这个,你仍然会得到一个错误-
      的糟糕例子是数值
      有太多的东西被识别为数字而不是数字。"-不正确。任何导致
      ISNUMERIC
      返回1的内容都可以转换为至少一种数字数据类型。问题是,我们不关心这种模糊的可能性-我们关心它是否可以转换为特定的数字数据类型,而这不是
      ISNUMERIC
      回答的问题。例如
      se选择CONVERT(money,“-”)
      是一种完全有效的转换方式。但您不在乎,因为您不打算将
      “-”
      转换为
      money
      数据类型。“识别为数字的东西太多了,而不是。”-不正确。任何导致
      ISNUMERIC
      返回1的内容都可以转换为至少一种数字数据类型。问题是,我们不关心这种模糊的可能性-我们关心它是否可以转换为特定的数字数据类型,而这不是
      ISNUMERIC
      回答的问题。例如
      se选择CONVERT(money,'-')
      是一种完全有效的转换。但是您不在乎,因为您不打算将
      '-'
      转换为
      money
      数据类型。