zaf*_*s.m 40 t-sql sql-server integer casting isnumeric
我想确定一个值是否为整数(如TryParse在.NET中).不幸的是ISNUMERIC,我不适合我,因为我只想解析整数而不是每种数字.有ISINT什么东西吗?
这里有一些代码可以清楚地表达出来.如果MY_FIELD不是int,则此代码将失败:
SELECT @MY_VAR = CAST(MY_FIELD AS INT)
FROM MY_TABLE
WHERE MY_OTHER_FIELD = 'MY_FILTER'
Run Code Online (Sandbox Code Playgroud)
谢谢
Sam*_*aan 35
基本上,它建议添加'.e0'值并使用IsNumeric.这样,任何已经有小数点的东西现在都有两个小数点,导致IsNumeric为假,并且任何已经用科学记数法表示的东西都被无效e0.
Iai*_*der 23
在他的文章中我可以将此字符串转换为整数吗?,Itzik Ben-Gan提供了纯T-SQL的解决方案和另一个使用CLR的解决方案.
您应该选择哪种解决方案?
T-SQL或CLR解决方案更好吗? 使用T-SQL解决方案的优点是您不需要超出T-SQL编程领域.但是,CLR解决方案有两个重要优点:它更简单,更快捷.当我针对具有1,000,000行的表测试两种解决方案时,CLR解决方案需要两秒钟,而不是七秒钟(对于T-SQL解决方案),可以在我的笔记本电脑上运行.因此,下次需要检查给定字符串是否可以转换为整数时,可以包含我在本文中提供的T-SQL或CLR解决方案.
如果您只想维护T-SQL,那么请使用纯T-SQL解决方案.如果性能比方便更重要,那么使用CLR解决方案.
纯T-SQL解决方案很棘手.它将内置的ISNUMERIC函数与模式匹配和转换相结合,以检查字符串是否表示int.
SELECT keycol, string, ISNUMERIC(string) AS is_numeric,
CASE
WHEN ISNUMERIC(string) = 0 THEN 0
WHEN string LIKE '%[^-+ 0-9]%' THEN 0
WHEN CAST(string AS NUMERIC(38, 0))
NOT BETWEEN -2147483648. AND 2147483647. THEN 0
ELSE 1
END AS is_int
FROM dbo.T1;
Run Code Online (Sandbox Code Playgroud)
CLR解决方案的T-SQL部分更简单.您调用fn_IsInt函数就像调用ISNUMERIC一样.
SELECT keycol, string, ISNUMERIC(string) AS is_numeric,
dbo.fn_IsInt(string) AS is_int
FROM dbo.T1;
Run Code Online (Sandbox Code Playgroud)
C#部分只是.NET解析函数Int32.TryParse的包装器.这是有效的,因为SQL Server int和.NET Int32都是32位有符号整数.
using System;
using System.Data.SqlTypes;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlBoolean fn_IsInt(SqlString s)
{
if (s.IsNull)
return SqlBoolean.False;
else
{
Int32 i = 0;
return Int32.TryParse(s.Value, out i);
}
}
};
Run Code Online (Sandbox Code Playgroud)
有关这些代码示例的完整说明,请阅读Itzik的文章.
101*_*010 14
使用sqlserver 2005及更高版本,您可以使用LIKE运算符使用类似regex的字符类.看到这里.
要检查字符串是否为非负整数(它是一个十进制数字序列),您可以测试它是否包含其他字符.
SELECT numstr
FROM table
WHERE numstr NOT LIKE '%[^0-9]%'
Run Code Online (Sandbox Code Playgroud)
注1:这也将返回空字符串.
注意2:使用LIKE '%[0-9]%'将返回包含至少一个数字的任何字符串.
看小提琴
小智 6
WHERE IsNumeric(MY_FIELD) = 1 AND CAST(MY_FIELD as VARCHAR(5)) NOT LIKE '%.%'
Run Code Online (Sandbox Code Playgroud)
这可能是最简单的解决方案.除非你MY_FIELD包含.00或类似的东西.在这种情况下,将其强制转换为浮动以删除任何尾随的.00s
死灵术。
从 SQL-Server 2012+ 开始,您可以使用 TRY_CAST,如果转换不成功,它会返回 NULL。
例子:
DECLARE @foo varchar(200)
SET @foo = '0123'
-- SET @foo = '-0123'
-- SET @foo = '+0123'
-- SET @foo = '+-0123'
-- SET @foo = '+-0123'
-- SET @foo = '.123'
-- SET @foo = '1.23'
-- SET @foo = '.'
-- SET @foo = '..'
-- SET @foo = '0123e10'
SELECT CASE WHEN TRY_CAST(@foo AS integer) IS NULL AND @foo IS NOT NULL THEN 0 ELSE 1 END AS isInteger
Run Code Online (Sandbox Code Playgroud)
这是唯一真正可靠的方法。
如果您需要 SQL-Server 2008 支持,请参考 Sam DeHaan 的回答:
SELECT CASE WHEN ISNUMERIC(@foo + '.e0') = 1 THEN 1 ELSE 0 END AS isInteger
Run Code Online (Sandbox Code Playgroud)
SQL-Server < 2012(又名 2008R2)将于 2019 年 7 月 9 日结束(扩展)支持。
此时,很快,对 < 2012 的支持就会被放弃。
此时我不会再使用任何其他黑客了。
只需告诉您节俭的客户进行更新即可 - 自 2008 年以来已经过去 10 多年了。
| 归档时间: |
|
| 查看次数: |
141873 次 |
| 最近记录: |