SQL SERVER ISNUMERIC函数判断数字不准确问题

本文介绍在SQL Server中如何使用ISNUMERIC函数及PATINDEX函数来判断字段是否为数值型,包括特殊字符的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

判断字段是不是数值型字段,SQL SERVER提供了ISNUMERIC函数:   

ISNUMERIC ( expression )

       当输入表达式的计算结果为有效的 numeric 数据类型时,ISNUMERIC 返回 1;否则返回 0。 有效的 numeric 数据类型包括以下类型:    

int

numeric

bigint

money

smallint

smallmoney

tinyint

float

decimal

real

       但是对于不是数字的字符(如加号 (+)、减号 (-))和有效货币符号(如美元符号 ($))字符,ISNUMERIC 也将返回 1。例子如下:    

--测试数据
if not object_id(N'Tempdb..#T') is null
	drop table #T
Go
Create table #T([col] nvarchar(22))
Insert #T
SELECT '3' UNION
        SELECT '123,67.00' UNION
        SELECT '¥2342' UNION        
        SELECT '$8888' UNION
        SELECT '+1'
Go
--测试数据结束

SELECT  *
FROM    #T
WHERE   ISNUMERIC(#T.col) = 1

       结果如下:

       我们可以看到¥、$ 、,+等字符都算做了数值型,如果我们恰巧需要这种的判断,那么非常好,我们可以直接用,但是如果我们的需求是不能把这些符号算作数值型,那么就不行了,我们可以利用PATINDEX 来实现

SELECT  *
FROM    #T
WHERE   PATINDEX('%[^0-9]%', #T.col) = 0

      结果如下:


      如果我们还需要“+-”号这些,那么可以稍作改动:

SELECT  *
FROM    #T
WHERE   PATINDEX('%[^0-9|.|-|+]%', #T.col) = 0

      结果如下:


      所以我们在判断数值型时,可以根据需求选择不用ISNUMERIC函数,而是选择更符合要求的写法。


<think>嗯,用户想在SQL Server中编写一个函数,从指定字符位置开始提取数字。我需要先理解他的需求。他提到的是从某个字符位置开始,所以可能需要指定起始点,然后从这个位置开始提取连续的数字部分。 首先,我应该回顾一下SQL Server中处理字符串的函数,比如SUBSTRING、PATINDEX、ISNUMERIC或者更新的版本中的TRY_CAST。过,用户可能需要一个自定义函数,因为内置函数可能无法直接满足需求。 用户提供的引用中,提到了几个相关的例子,比如引用[1]和[2]都是关于提取字符串中的数字部分,可能可以参考这些方法。例如,使用循环逐个字符检查是否是数字,然后拼接起来。 接下来,我需要考虑如何设计这个函数函数可能需要两个参数:原始字符串和开始位置。然后从该位置开始遍历每个字符,直到遇到非数字字符为止。需要注意的是,开始位置是否有效,比如是否超出字符串长度,或者是否负数,需要处理这些情况。 然后,考虑到SQL Server中处理字符串的方式,可能需要使用WHILE循环,逐个字符检查是否是数字。在SQL中,可以使用SUBSTRING函数来获取特定位置的字符,再使用PATINDEX或者LIKE来判断是否是数字。例如,使用字符 LIKE '[0-9]'来判断是否是数字。 另外,需要处理开始位置的索引问题SQL Server中的SUBSTRING函数是从1开始的,所以用户传入的位置如果是基于0的话需要调整。过用户可能希望按照SQL的惯例,起始位置从1开始,所以可能需要明确这一点。 可能的函数逻辑如下: 1. 检查开始位置是否在有效范围内(大于0且大于字符串长度)。 2. 初始化变量,比如结果字符串和当前位置。 3. 从开始位置循环每个字符,如果是数字则追加到结果中,否则退出循环。 4. 返回结果字符串。 还需要考虑性能问题,因为循环处理可能在大数据量时效率高,但作为自定义函数,这可能无法避免。另外,是否处理前导零的情况,用户可能需要保留所有数字,包括前导零,所以需要额外处理。 测试用例也很重要,比如测试字符串'abc123def456',从位置4开始提取,应该得到'123'。或者从位置7开始,得到'456'。另外,开始位置超出范围时返回空字符串。 现在,结合引用中的例子,比如引用[1]中的自定义函数,可能使用类似的方法,逐个字符判断并拼接。例如,使用WHILE循环,从指定位置开始,逐个检查字符是否为数字,直到遇到非数字为止。 最后,给出示例用法,并提醒用户注意开始位置的索引是从1开始,以及如何处理无效位置的情况。</think>### 分步解答:在 SQL Server 中提取指定位置开始的数字 #### 1. 函数设计思路 通过以下步骤实现从指定位置提取数字: - **输入参数**:字符串 `@str` 和起始位置 `@start_pos` - **逐字符遍历**:从起始位置开始检查每个字符是否为数字 - **终止条件**:遇到非数字字符或字符串结束 - **返回结果**:拼接后的连续数字字符串 #### 2. 完整函数代码 ```sql CREATE FUNCTION dbo.fn_ExtractNumbersFromPosition ( @str VARCHAR(MAX), @start_pos INT ) RETURNS VARCHAR(MAX) AS BEGIN DECLARE @result VARCHAR(MAX) = '' DECLARE @i INT = @start_pos DECLARE @len INT = LEN(@str) -- 验证起始位置有效性 IF @start_pos < 1 OR @start_pos > @len RETURN '' WHILE @i <= @len BEGIN IF SUBSTRING(@str, @i, 1) LIKE '[0-9]' SET @result = @result + SUBSTRING(@str, @i, 1) ELSE BREAK SET @i = @i + 1 END RETURN @result END ``` #### 3. 关键参数说明 | 参数 | 类型 | 说明 | |------|------|------| | @str | VARCHAR(MAX) | 原始输入字符串 | | @start_pos | INT | 起始位置(从1开始) | #### 4. 使用示例 ```sql -- 示例1:从第4个字符开始提取 SELECT dbo.fn_ExtractNumbersFromPosition('abc123def456', 4) -- 返回 '123' -- 示例2:起始位置超出范围 SELECT dbo.fn_ExtractNumbersFromPosition('test', 10) -- 返回 '' ``` #### 5. 注意事项 1. **起始位置有效性**:自动处理超出范围的情况 2. **性能优化**:避免在超长字符串上频繁调用 3. **字符集兼容性**:仅处理标准ASCII数字字符(0-9) ### 引用说明 此方法通过逐字符扫描实现数字提取,类似字符串处理函数的实现逻辑[^1][^2]。对于更复杂的字符串解析需求,可结合正则表达式功能或CLR集成实现[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值