t-sql判断一个字符串是否为bigint的函数(全角数字需要判断为不合格)

本文介绍了一种在T-SQL中验证字符串是否能转换为bigint的方法,并提供了一个自定义函数实现。该函数通过多种方式检查字符串的有效性,包括去除非法符号、验证长度及使用COLLATE关键字区分全角半角字符。


作者: 左其盛 发表于 2010-07-18 22:30 原文链接 阅读: 131 评论: 0

最近在做的一个项目遇到这么一个问题:需要把一个字符串格式的卡号转换为bigint格式的卡号。t-sql自带的isnumeric函数不能用。它认为合格的数字不一定是bigint,比如一些带小数点的数字,科学计数的数字。上网搜,中文资料中没发现有帮助的,在sqlservercentral上发现有人写过这个函数了。关键的算法就是charindex + substring循环,一个一个看有没有不合法的字符。文章的评论中有人说可以用patindex函数,更快。不过用了这两个都解决不了全角数字的问题,他们都认为全角数字是合法的数字,当然实际转换为bigint的时候会报错。
 
 又上网搜了搜,注意到了COLLATE关键字。一般的解释是它可以指定排序规则。可以改变的规则有大小写、重音、假名(日语才有)、全角半角。中文系统中很少用到这个关键字。一般就用默认的大小写不敏感。我这里想区分全角半角,必须用COLLATE关键字。可以这么用:charindex(substring(@s, @i, 1), '0123456789' COLLATE  Chinese_PRC_CS_AS_KS_WS),其中COLLATE后面的参数中Chinese_PRC指定字符集所使用的代码页(其实就是所用的语言),后面最多可以跟四个×s,S表示敏感,对应的I表示不敏感。比如Chinese_PRC_CS_AS_KS_WS表示是简体中文,大小写敏感(CS),重音敏感(AS,这个对汉语没意义),区分假名类型(KS,这个对汉语也没意义),区分全角半角(KS),Chinese_PRC_CI_AI表示简体中文,大小写不敏感,重音不敏感,不区分假名类型,不区分全角半角。后两个参数忽略掉就表示否定。当然还可以直接指定二进制排序,全角半角的问题就自然解决了,而且二进制排序还更快一些:charindex(substring(@s, @i, 1), '0123456789' COLLATE  Chinese_PRC_BIN)
 
 因此,理论上这个判断字符串是否为bigint的问题的核心算法有四种解决方案:
 
 charindex(substring(@s, @i, 1), '0123456789' COLLATE  Chinese_PRC_CS_AS_KS_WS)
 charindex(substring(@s, @i, 1), '0123456789' COLLATE  Chinese_PRC_BIN)
 patindex('%[^0-9]%',@s COLLATE  Chinese_PRC_CS_AS_KS_WS )
 patindex('%[^0-9]%',@s COLLATE  Chinese_PRC_BIN )
 
 不过实验发现第三种不能解决问题,仍然认为全角数字是合法的数字。看微软msdn文档,上网搜都没有找到答案。其他三种都可以。理论上最后一种最快。
 
 下面是完整的函数的代码:


/*
-- Tests pass isnumeric AND fail IsBigInt AND fail cast(vc as bigint)

-- range
SELECT IsNumeric('-9223372036854775809'), dbo.IsBigInt('-9223372036854775809')
SELECT IsNumeric('9223372036854775808'), dbo.IsBigInt('9223372036854775808')

-- invalid chars
SELECT IsNumeric('-5d2'), dbo.IsBigInt('-5d2')
SELECT IsNumeric('-5e2'), dbo.IsBigInt('-5e2')
SELECT IsNumeric('+3,4'), dbo.IsBigInt('+3,4')
SELECT IsNumeric('+3.4'), dbo.IsBigInt('+3.4')

-- pass this strange case
SELECT IsNumeric('00000000000000000000000000001'), dbo.IsBigInt('00000000000000000000000000001')
*/

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.IsBigInt') AND type IN (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION dbo.IsBigInt
GO

CREATE FUNCTION dbo.IsBigInt (@a varchar(30))
returns bit
AS
BEGIN
 -- Submitted to SqlServerCentral by William Talada
 DECLARE
  @s varchar(30),
  @i int,
  @IsNeg bit,
  @valid int

 -- assume the best
 SET @valid = 1
 SET @IsNeg=0
 SET @s = ltrim(rtrim(@a))

 -- strip OFF negative sign
 IF len(@s) > 0
 AND LEFT(@s, 1) = '-'
 BEGIN
  SET @IsNeg=1
  SET @s = RIGHT(@s, len(@s) - 1)
 END

 -- strip OFF positive sign
 IF len(@s) > 0
 AND LEFT(@s, 1) = '+'
 BEGIN
  SET @s = RIGHT(@a, len(@a) - 1)
 END

 -- strip leading zeros
 while len(@s) > 1 and left(@s,1) = '0'
  set @s = right(@s, len(@s) - 1)

 -- 19 digits max
 IF len(@s) > 19 SET @valid = 0

 -- the rest must be numbers only
 --SET @i = len(@s)

 --WHILE @i >= 1
 --BEGIN
 ----IF charindex(substring(@s, @i, 1), '0123456789' COLLATE  Chinese_PRC_CI_AS_WS ) = 0 SET @valid = 0
 -- IF charindex(substring(@s, @i, 1), '0123456789' COLLATE  Chinese_PRC_BIN ) = 0 SET @valid = 0

 -- SET @i = @i - 1
 --END
 
 --if patindex('%[^0-9]%',@s COLLATE  Chinese_PRC_CI_AS_WS )>0
 if patindex('%[^0-9]%',@s COLLATE  Chinese_PRC_BIN )>0
  set @valid=0


 -- check range
 IF @valid = 1 AND len(@s) = 19
 BEGIN
  IF @isNeg = 1 AND @s > '9223372036854775808' SET @valid = 0
  IF @IsNeg = 0 AND @s > '9223372036854775807' SET @valid = 0
 END

 RETURN @valid
END
go

评论: 0 查看评论 发表评论

百度期待您的加盟


最新新闻:
· 微软不为外界所知的十件趣事(2010-07-18 22:58)
· 中国第2季搜索引擎市场规模达26亿 百度破70%(2010-07-18 22:54)
· Facebook用户数下周达5亿 邀请用户共享故事(2010-07-18 22:49)
· 开源的可视化编辑器 KindEditor 3.5.1 发布(2010-07-18 22:35)
· WordPress 陷入开源‘边界’之争(2010-07-18 17:47)

编辑推荐:揭秘Facebook背后的那些软件

网站导航:博客园首页  个人主页  新闻  闪存  小组  博问  社区  知识库

<think>首先,用户查询是:“我想了解如何在SQL中使用CAST函数字符串转换为数字,请问SQLCAST函数字符串数字示例8000006841”。这表明用户想在SQL中使用CAST函数字符串转换为数字,并提供示例数字:8000006841。用户引用了几个参考内容:[^1],[^2],[^3],[^4],[^5]。让我回顾这些引用:-[^1]:显示使用CAST或CONVERT函数字符串转换为数字的MySQL示例:ORDERBYCAST(your_columnASUNSIGNED);。-[^2]:介绍MySQL的CASTCONVERT函数,用于数据类型转换。-[^3]:提供CAST函数的详细语法参数描述。-[^4]:讨论CASTCONVERT在SQLServer中的使用,提到CAST适用于基本转换。-[^5]:似乎关于SQL字符串函数,但用户引用中提到“用于字符串的聚合函数”,可能与查询无关。用户指定了数字:8000006841,所以我应该以此为例创建一个示例。系统级指令:1.行内数学表达式使用$...$格式。如$x^2$。2.独立公式使用$$...$$格式并单独成段。3.LaTeX语法正确。4.使用中文回答。5.生成相关问题。6.在引用的段落末尾添加引用标识,例如:[^1]。用户可见层指令:-回答结构清晰,帮助用户逐步解决问题,保证真实可靠。用户说:“上述引用仅供参考,并是用户真正的需求,请尽可能多的参考用户上一次的问题你的回答。”但在这个新会话中,没有“上一次的问题”,因为这是新的。用户引用了5个内容,但我应该主要基于用户的直接查询来回答。我的回答结构:1.**理解用户需求**:解释CAST函数用于将字符串转换为数字的基本概念。2.**语法**:提供CAST函数的通用语法。3.**示例**:以用户的数字8000006841为例子,提供SQL示例。4.**注意事项**:基于引用,讨论可能的错误最佳实践。5.**生成相关问题**:在结尾添加相关问题。在引用末尾添加引用标识。所以,当我提到引用内容时,需要添加[^n]。逐步构建回答:-**介绍CAST函数**:CAST函数用于将表达式从一种数据类型转换为另一种,如字符串数字-**语法参考[^3]**:CAST(exprAStarget_type)-**目标类型**:对于数字,可以是INT、BIGINT、DECIMAL等。-**示例**:用户提供了8000006841,所以我假设这是一个字符串列的值。例如:如果有一个表`your_table`,列`your_column`包含字符串数字SQL查询示例:-在MySQL:SELECTCAST('8000006841'ASUNSIGNED);或SELECTCAST(your_columnASUNSIGNED)FROMyour_table;-SQLServer或其他数据库类似。-**注意事项**:-转换失败时会引发错误,如字符串包含非数字字符[^4]。-使用UPPER/LOWER函数确保兼容性。生成相关问题:如“如何处理转换失败?”、“CASTCONVERT的区别?”等。使用中文回答。最终回答结构:1.解释CAST函数。2.提供语法示例。3.添加注意事项。4.结尾生成相关问题。添加引用标识:比如在提到引用内容时加[^1]。例如:大多数数据库支持CAST函数来转换字符串数字[^1]。示例代码块:用户提供了数字8000006841,所以我可以用它。SQL示例可以是:SELECTCAST('8000006841'ASDECIMAL(20,0));--适合大数字。在MySQL,使用UNSIGNED或SIGNEDINT可能够,因为8000006841是大的,大约8e9,INT最大2e9左右,所以用BIGINT或DECIMAL更好。在SQL中,INT通常是4字节,最大约2e9,BIGINT是8字节,最大约9e18,所以8000006841(8e9)适合BIGINT。或者使用DECIMAL指定精度。在CAST中,可以用CAST(exprASBIGINT)或CAST(exprASDECIMAL(10,0))。提供具体示例。在回答中,逐步引导用户。</think> 以下是针对您的查询“如何在SQL中使用CAST函数字符串转换为数字”的逐步解答。我将基于SQL标准及多数据库系统(如MySQLSQL Server、PostgreSQL等)进行说明。CAST函数用于将表达式从一种数据类型转换为另一种,这里我们专注于将字符串转换为数字类型。在SQL中,数字类型包括INT(整数)、BIGINT(大整数)、DECIMAL(十进制数)等。使用CAST转换时,需确保字符串内容全是数字或可解析为数字,否则会引发错误[^4]。 您的示例数字“8000006841”是一个较大整数(约8e9),适合用BIGINT或DECIMAL类型处理,因为标准INT类型(最大约2e9)可能无法容纳这个值[^3]。我会提供通用语法具体示例,并标注关键点以保持结构清晰。 ### 1. **CAST函数的基本语法与原理** CAST函数的通用语法如下: ```sql CAST(expression AS target_data_type) ``` - **expression**:要转换的SQL表达式,通常是字符串文字或表中的列(如 `'8000006841'` 或 `your_column`)。 - **target_data_type**:目标数字类型,常用选项: - `INT` 或 `INTEGER`(小整数,支持±2e9范围)。 - `BIGINT`(大整数,支持±9e18范围,适用于大数字如8000006841)。 - `DECIMAL(p[, s])`(十进制数,p是总位数精度,s是小数位数;如果省略s,默认为0)。 例如,`CAST('123' AS INT)` 将字符串"123"转换为整数123。 当字符串包含非数字字符(如字母或符号)时,转换会失败并引发错误[^4]。因此,实际应用中建议先用函数如 `TRIM()` 或 `REPLACE()` 清理数据,或添加错误处理机制[^3]。 ### 2. **CAST字符串数字的示例** 根据您提供的数字“8000006841”,我会展示在同场景下的SQL示例。注意: - **数据库兼容性**:CAST是SQL标准函数,支持MySQLSQL Server、PostgreSQL等主流系统。 - **目标类型选择**:由于8000006841太大(超INT上限),优先使用BIGINT或DECIMAL。DECIMAL可指定精度,如 `DECIMAL(10,0)` 表示总位数10、无小数。 - **示例格式**:使用代码块展示SQL语句输出。 #### 示例 1: 直接转换文字字符串一个硬编码的字符串(如"8000006841")转换为数字: ```sql -- 在MySQL中转换为无符号整数(使用BIGINT处理大数字) SELECT CAST('8000006841' AS UNSIGNED) AS result; -- 输出:8000006841 --SQL Server或PostgreSQL中转换为BIGINT SELECT CAST('8000006841' AS BIGINT) AS result; -- 输出:8000006841 ``` #### 示例 2: 转换表列中的字符串数据 假设有一个表 `your_table`,包含列 `your_column`(存储字符串数字),查询并排序: ```sql -- 通用示例:查询并转换列值(目标类型用DECIMAL避免溢出) SELECT your_column, CAST(your_column AS DECIMAL(10, 0)) AS numeric_value FROM your_table ORDER BY CAST(your_column AS DECIMAL(10, 0)); ``` - **解释**:`DECIMAL(10, 0)` 指定了10位总精度、无小数位,适合8000006841这种整数。排序时基于数字值,而非字符串的字典序[^1]。 #### 示例 3: 集成到其他查询中(如WHERE或JOIN) 在WHERE子句中转换后比较数字: ```sql SELECT * FROM your_table WHERE CAST(your_column AS BIGINT) > 8000000000; -- 比较数字值 ``` - **输出**:返回 `your_column` 大于8e9的记录,数字比较更准确。 ### 3. **注意事项最佳实践** - **错误处理**:如果字符串包含非数字内容(如 "8000006841abc"),会引发转换错误[^4]。避免此问题: - 使用 `ISNUMERIC()` 或类似函数先检查有效性(SQL Server支持 `TRY_CAST` 避免硬错误)。 - 清理数据:`CAST(REPLACE(your_column, '-', '') AS BIGINT)` 移除干扰字符。 - **精度与溢出**:选择目标类型时,确保精度足够。例如: -BIGINT或DECIMAL处理大数字,防止INT溢出[^3]。 - 在MySQL中,UNSIGNED可选,但BIGINT更安全。 - **性能**:CAST在排序或计算时效率高,但如果表数据量大,建议在表设计时直接使用数字类型列,以减少运行时开销[^1]。 - **替代函数**:某些数据库如SQL Server推荐使用CONVERT,因为它支持格式代码(如日期转换),但CAST更简单标准[^4]。 ### 相关问题 为了帮助您深入学习SQL数据类型转换,以下是基于本主题的相关问题: 1. SQL中如何处理CAST转换失败的错误? 2. CASTCONVERT函数SQL中有哪些主要区别? 3. 除了CAST,还有哪些函数可以用于SQL字符串数字的转换? 4. 在包含小数点的字符串转换时,如何指定DECIMAL的精度小数位? 5. 如何优化数据库表以减少频繁的字符串数字转换? 通过以上解答示例,您可以实践将字符串“8000006841”或其他数字高效转换为SQL数字类型。如果有更具体的数据库环境(如MySQLSQL Server)或场景需求,请提供更多细节,我会调整回答![^1][^2][^3][^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值