SQL IsNumeric无法正常工作

时间:2011-09-27 10:41:24

标签: sql sql-server

保留列是一个varchar,对它执行求和我想将它转换为deciaml。 但下面的SQL给了我一个错误

select
cast(Reserve as decimal)
from MyReserves

将数据类型varchar转换为数字时出错。

我添加了isnumeric而不是null来尝试避免此错误,但它仍然存在,任何想法为什么?

select
cast(Reserve as decimal)
from MyReserves
where isnumeric(Reserve ) = 1
and MyReserves is not null

11 个答案:

答案 0 :(得分:8)

见这里:CAST and IsNumeric

试试这个:

WHERE IsNumeric(Reserve + '.0e0') = 1 AND reserve IS NOT NULL

<强>更新

十进制的默认值是(18,0),所以

declare @i nvarchar(100)='12121212121211212122121'--length is>18 
SELECT ISNUMERIC(@i) --gives 1
SELECT CAST(@i as decimal)--throws an error

答案 1 :(得分:4)

天哪,似乎没有人正确解释这一点。 SQL是一种描述性语言。它没有指定操作顺序。

您(好吧,有)的问题是where在转换发生之前没有进行过滤。但是,案例陈述保证了操作顺序。因此,以下内容将起作用:

select cast(case when isnumeric(Reserve) = 1 then Reserve end as decimal)
from MyReserves
where isnumeric(Reserve ) = 1 and MyReserves is not null

此问题与您要转换为或使用isnumeric()功能的特定数字格式无关。简单地说,不保证操作的顺序。

答案 2 :(得分:2)

似乎isnumeric有一些问题:

http://www.sqlhacks.com/Retrieve/Isnumeric-problems (通过互联网档案)

根据该链接,你可以这样解决:

select
cast(Reserve as decimal)
from MyReserves
where MyReserves is not null
and MyReserves * 1 = MyReserves 

答案 3 :(得分:2)

使用try_cast(sql 2012)

select
try_cast(Reserve as decimal)
from MyReserves

答案 4 :(得分:1)

isnumeric在SQL中不是100%可靠 - 请参阅此问题Why does ISNUMERIC('.') return 1?

我猜你在通过isnumeric测试的保留列中有值但不会转换为十进制。

答案 5 :(得分:1)

只是提高了isnumeric;如果字符串包含一些数字并且后跟一些数字的“E”,则将其视为指数。例如,select isnumeric('123E0')返回1.

答案 6 :(得分:1)

我遇到了同样的问题,结果证明它是科学记数法,例如'1.72918E-13'要找到这样做,只需要保留LIKE'%E%'。尝试绕过这些并查看它是否有效。您必须编写代码将这些代码转换为可用的东西或重新格式化您的源文件,这样它就不会使用科学记数法存储任何数字。

答案 7 :(得分:0)

IsNumeric在你的场景中可能并不理想,因为突出显示的注意事项MSDN page它说“ISNUMERIC为某些不是数字的字符返回1,例如加号(+),减号( - )和有效的货币符号,如美元符号($)。“

还有一篇很好的文章here,它进一步讨论了ISNUMERIC

答案 8 :(得分:0)

尝试(例如):

select
cast(Reserve as decimal(10,2))
from MyReserves

Numeric / Decimal通常需要精度和刻度。

答案 9 :(得分:0)

IsNumeric是一个有问题的孩子 - SQL 2012及更高版本有TRY_CAST and TRY_CONVERT

如果您使用的是早期版本,则可以编写一个转换为十进制的函数(如果不转换则为NULL)。这使用的XML转换函数在数字不适合时不会抛出错误;)

-- Create function to convert a varchar to a decimal (returns null if it fails)
IF EXISTS( SELECT * FROM sys.objects WHERE object_id = OBJECT_ID( N'[dbo].[ToDecimal]' ) AND type IN( N'FN',N'IF',N'TF',N'FS',N'FT' ))
    DROP FUNCTION [dbo].[ToDecimal];
GO

CREATE FUNCTION ToDecimal
(   
    @Value VARCHAR(MAX)
)
RETURNS DECIMAL(18,8)
AS
BEGIN
    -- Uses XML/XPath to convert @Value to Decimal because it returns NULL it doesn't cast correctly
    DECLARE @ValueAsXml XML
    SELECT @ValueAsXml = Col FROM (SELECT (SELECT @Value as Value FOR XMl RAW, ELEMENTS) AS Col) AS test
    DECLARE @Result DECIMAL(38,10)
    -- XML/XPath will return NULL if the VARCHAR can't be converted to a DECIMAL(38,10)
    SET @Result =  @ValueAsXml.value('(/row/Value)[1] cast as xs:decimal?', 'DECIMAL(38,10)')
    RETURN CASE -- Check if the number is within the range for a DECIMAL(18,8)
        WHEN @Result >= -999999999999999999.99999999 AND @Result <= 999999999999999999.99999999
            THEN CONVERT(DECIMAL(18,8),@Result) 
        ELSE 
            NULL
    END
END

然后只需将您的查询更改为:

select dbo.ToDecimal(Reserve) from MyReserves

答案 10 :(得分:0)

我也面临这个问题,我通过以下方法解决了。我正在分享这个,因为它可能对某些人有帮助。

import { Injectable } from '@angular/core';

@Injectable()
export class Loggly {
  private LTracker: any;

  constructor() {

    this.LTracker = this.LTrack(window, document) || [];
    this.LTracker.push({
      'logglyKey': 'YOUR_KEY_HERE',
      'sendConsoleErrors' : true,
      'tag' : 'loggly-jslogger'
    });
  }

  push(props) {
    this.LTracker.push(props);
  }

  LTrack (window, document) {
    var LOGGLY_INPUT_PREFIX = 'http' + (('https:' === document.location.protocol ? 's' : '')) + '://',
      LOGGLY_COLLECTOR_DOMAIN = 'logs-01.loggly.com',
      LOGGLY_SESSION_KEY = 'logglytrackingsession',
      LOGGLY_SESSION_KEY_LENGTH = LOGGLY_SESSION_KEY.length + 1,
      LOGGLY_PROXY_DOMAIN = 'loggly';

    function uuid() {
      // lifted from here -> http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
      });
    }

    function LogglyTracker() {
      this.key = false;
      this.sendConsoleErrors = false;
      this.tag = 'jslogger';
      this.useDomainProxy = false;
    }

    function setKey(tracker, key) {
      tracker.key = key;
      tracker.setSession();
      setInputUrl(tracker);
    }

    function setTag(tracker, tag) {
      tracker.tag = tag;
    }

    function setDomainProxy(tracker, useDomainProxy) {
      tracker.useDomainProxy = useDomainProxy;
      //refresh inputUrl value
      setInputUrl(tracker);
    }

    function setSendConsoleError(tracker, sendConsoleErrors) {
      tracker.sendConsoleErrors = sendConsoleErrors;

      if (tracker.sendConsoleErrors === true) {
        var _onerror = window.onerror;
        //send console error messages to Loggly
        window.onerror = function (msg, url, line, col, err){
          tracker.push({
            category: 'BrowserJsException',
            exception: {
              message: msg,
              url: url,
              lineno: line,
              colno: col,
              stack: err ? err.stack : 'n/a',
            }
          });

          if (_onerror && typeof _onerror === 'function') {
            _onerror.apply(window, arguments);
          }
        };
      }
    }

    function setInputUrl(tracker) {

      if (tracker.useDomainProxy == true) {
        tracker.inputUrl = LOGGLY_INPUT_PREFIX
          + window.location.host
          + '/'
          + LOGGLY_PROXY_DOMAIN
          + '/inputs/'
          + tracker.key
          + '/tag/'
          + tracker.tag;
      }
      else {
        tracker.inputUrl = LOGGLY_INPUT_PREFIX
          + (tracker.logglyCollectorDomain || LOGGLY_COLLECTOR_DOMAIN)
          + '/inputs/'
          + tracker.key
          + '/tag/'
          + tracker.tag;
      }
    }

    LogglyTracker.prototype = {
      setSession: function (session_id) {
        if (session_id) {
          this.session_id = session_id;
          this.setCookie(this.session_id);
        } else if (!this.session_id) {
          this.session_id = this.readCookie();
          if (!this.session_id) {
            this.session_id = uuid();
            this.setCookie(this.session_id);
          }
        }
      },
      push: function (data) {
        var type = typeof data;

        if (!data || !(type === 'object' || type === 'string')) {
          return;
        }

        var self = this;


        if (type === 'string') {
          data = {
            'text': data
          };
        } else {
          if (data.logglyCollectorDomain) {
            self.logglyCollectorDomain = data.logglyCollectorDomain;
            return;
          }

          if (data.sendConsoleErrors !== undefined) {
            setSendConsoleError(self, data.sendConsoleErrors);
          }

          if (data.tag) {
            setTag(self, data.tag);
          }

          if (data.useDomainProxy) {
            setDomainProxy(self, data.useDomainProxy);
          }

          if (data.logglyKey) {
            setKey(self, data.logglyKey);
            return;
          }

          if (data.session_id) {
            self.setSession(data.session_id);
            return;
          }
        }

        if (!self.key) {
          return;
        }

        self.track(data);


      },
      track: function (data) {
        // inject session id
        data.sessionId = this.session_id;

        try {
          //creating an asynchronous XMLHttpRequest
          var xmlHttp = new XMLHttpRequest();
          xmlHttp.open('POST', this.inputUrl, true); //true for asynchronous request
          xmlHttp.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');
          xmlHttp.send(JSON.stringify(data));

        } catch (ex) {
          if (window && window.console && typeof window.console.log === 'function') {
            console.log("Failed to log to loggly because of this exception:\n" + ex);
            console.log("Failed log data:", data);
          }
        }
      },
      /**
       *  These cookie functions are not a global utilities.  It is for purpose of this tracker only
       */
      readCookie: function () {
        var cookie = document.cookie,
          i = cookie.indexOf(LOGGLY_SESSION_KEY);
        if (i < 0) {
          return false;
        } else {
          var end = cookie.indexOf(';', i + 1);
          end = end < 0 ? cookie.length : end;
          return cookie.slice(i + LOGGLY_SESSION_KEY_LENGTH, end);
        }
      },
      setCookie: function (value) {
        document.cookie = LOGGLY_SESSION_KEY + '=' + value;
      }
    };

    var existing = window._LTracker;

    var tracker = new LogglyTracker();

    if (existing && existing.length) {
      var i = 0,
        eLength = existing.length;
      for (i = 0; i < eLength; i++) {
        tracker.push(existing[i]);
      }
    }

     return tracker;
  };
}