sql – 检查字符是否为数字的最快方法?

我遇到sqlserver的ISNUMERIC函数问题,它为’,’返回true

我正在解析一个邮政编码并试图查看第二个字符(应该是一个数字)是否为0,并在每种情况下做一些不同的事情.问题是我不能通过首先检查isNumeric来转换char.这是我的标量值函数的代码,用于返回第二个char位置的数字,如果不是数字,则返回-1.

@declare firstDigit int

IF ISNUMERIC(SUBSTRING(@postal,2,1) AS int) = 1
   set @firstDigit = CAST(SUBSTRING(@postal,2,1) AS int)
ELSE
   set @firstDigit = -1       

RETURN @firstdigit

由于这在邮政编码不太有效时失败了.我只是试图找出如何检查nvarchar @postal的第二个字符是否是0-9的数字.我见过不同类型的解决方案,比如使用LIKE [0-9]或使用PATINDEX等.

是否有更好/更简单的方法来做到这一点,如果不是哪种方法将是最快的?

编辑:根据Aaron Bertrand的建议添加代码

ON z.postal = 
   CASE
      WHEN CONVERT(INT, CASE WHEN SUBSTRING(v.patientPostal,2,1) LIKE '[0-9]' 
          THEN SUBSTRING(v.patientPostal, 2,1) END) = 0 then v.patientPostal
      WHEN CONVERT(INT, CASE WHEN SUBSTRING(v.patientPostal,2,1) LIKE '[0-9]' 
          THEN SUBSTRING(v.patientPostal, 2,1) END) > 0 then LEFT(v.patientPostal,3)
最佳答案
如果你能够发现WHERE col LIKE'[0-9]’和你想出的任何其他方法之间的任何区别,我会感到非常惊讶.但我同意Denis,将其放在一个函数中,以便在所有代码中始终如一地使用相同的检查(或者至少,如果由于大扫描等而避免使用UDF,请在代码中添加一个标记,以后可以很容易地进行大范围的改变.

也就是说,通过使用标量UDF而不是用于在函数内部解析的方法,您肯定会看到更多的性能损失.你真的应该比较UDF的性能与使用CASE进行内联的性能.例如

SELECT Postal = CONVERT(INT, CASE WHEN SUBSTRING(postal,2,1) LIKE '[0-9]' 
       THEN SUBSTRING(postal, 2,1) END)
FROM ...

如果字符不是数字,则将产生NULL.

如果您只是在处理检查局部变量,那么使用哪种解析方法并不重要,最好将优化工作集中在其他地方.

编辑添加建议到演示JOIN子句.这可能会导致扫描更少的持续时间,但是更具可读性(更少的子串调用等):

;WITH v AS 
(
    SELECT /* other columns, */ patientPostal, 
      ss = SUBSTRING(v.patientPostal,2,1),
      FROM [whatever table is aliased v in current query]
)
SELECT /* column list */
FROM [whatever table is aliased z in current query]
INNER JOIN v ON z.postal = CONVERT(INT, CASE 
    WHEN v.ss = '0' THEN ss
    WHEN v.ss LIKE '[1-9]' THEN LEFT(v.patientPostal, 3)
END);

转载注明原文:sql – 检查字符是否为数字的最快方法? - 代码日志