今天在论坛上看到一个问题,如下:
解决这个问题,Insus.NET写了一个函数,可以方便以后的扩展,如果数值出现TB或是或更高时,可以只改这个函数即可。


SET
ANSI_NULLS
ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [ dbo ] . [ udf_OrderLimitSize ]
(
@Ov NVARCHAR ( 30 )
)
RETURNS decimal ( 18 , 6 )
AS
BEGIN
-- 如果长度少于等于2的数值为返回NULL
IF ( LEN ( @Ov ) <= 2 )
RETURN NULL
-- 宣告两个变量
DECLARE @v DECIMAL ( 18 , 6 ), @n DECIMAL ( 18 , 6 )
-- 判断最后两位数是否为下面这些单位
IF ( RIGHT ( @Ov , 2 ) NOT IN ( ' TB ' , ' GB ' , ' MB ' , ' KB ' ))
RETURN NULL
-- 去掉最后两位数之后,把值转为DECIMAL数据类型
SET @n = CONVERT ( DECIMAL ( 18 , 6 ), LEFT ( @Ov , LEN ( @Ov ) - 2 ))
-- 判断截除最后两位数之后,使用ISNUMERIC判断是否为有效的数值,如果不是返回NULL
IF ( ISNUMERIC ( @n ) = 0 )
RETURN NULL
-- 下面做单位转算,如果遇上有新单位时,可以作相应添加
IF ( @Ov LIKE ' %TB ' )
SET @v = @n * 1024 * 1024 * 1024
IF ( @Ov LIKE ' %GB ' )
SET @v = @n * 1024 * 1024
IF ( @Ov LIKE ' %MB ' )
SET @v = @n * 1024
IF ( @Ov LIKE ' %KB ' )
SET @v = @n
RETURN @v
END
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [ dbo ] . [ udf_OrderLimitSize ]
(
@Ov NVARCHAR ( 30 )
)
RETURNS decimal ( 18 , 6 )
AS
BEGIN
-- 如果长度少于等于2的数值为返回NULL
IF ( LEN ( @Ov ) <= 2 )
RETURN NULL
-- 宣告两个变量
DECLARE @v DECIMAL ( 18 , 6 ), @n DECIMAL ( 18 , 6 )
-- 判断最后两位数是否为下面这些单位
IF ( RIGHT ( @Ov , 2 ) NOT IN ( ' TB ' , ' GB ' , ' MB ' , ' KB ' ))
RETURN NULL
-- 去掉最后两位数之后,把值转为DECIMAL数据类型
SET @n = CONVERT ( DECIMAL ( 18 , 6 ), LEFT ( @Ov , LEN ( @Ov ) - 2 ))
-- 判断截除最后两位数之后,使用ISNUMERIC判断是否为有效的数值,如果不是返回NULL
IF ( ISNUMERIC ( @n ) = 0 )
RETURN NULL
-- 下面做单位转算,如果遇上有新单位时,可以作相应添加
IF ( @Ov LIKE ' %TB ' )
SET @v = @n * 1024 * 1024 * 1024
IF ( @Ov LIKE ' %GB ' )
SET @v = @n * 1024 * 1024
IF ( @Ov LIKE ' %MB ' )
SET @v = @n * 1024
IF ( @Ov LIKE ' %KB ' )
SET @v = @n
RETURN @v
END
下面为了应用这个函数,例举例子:
CREATE
TABLE
test(id
int
identity
(
1
,
1
),size
NVARCHAR
(
50
))
GO
INSERT INTO [ test ] values ( ' 23.5mb ' ),( ' 10gb ' ),( ' 12.7mb ' ),( ' 8GB ' )
go
SELECT [ id ] , [ size ] FROM test ORDER BY [ dbo ] . [ udf_OrderLimitSize ] ( [ size ] )
GO
INSERT INTO [ test ] values ( ' 23.5mb ' ),( ' 10gb ' ),( ' 12.7mb ' ),( ' 8GB ' )
go
SELECT [ id ] , [ size ] FROM test ORDER BY [ dbo ] . [ udf_OrderLimitSize ] ( [ size ] )
执行结果: