好久没有写有关SqlServer 数据库方面技术的文章了,正好今天遇到了一个问题,我就把这个当做一个练习记录下来。今天遇到一个麻烦事,详情如下:公司买了一个系统,在这个系统里面有一个“充值卡”的功能,但是充值卡的当前所剩下的金额已经被乱码了,看不出来真正的金额,而且,卖软件的那家公司把所有的Sql 函数和存储过程都加密了,没有办法看到。
怎么办?为了和公司的其他系统进行集成,于是,我就试试来写一个逆运算来还原当前“充值卡”的剩余金额,搞了一天终于搞出来了。其实这个东西不是很难,只是刚开始的时候什么也不知道,东找西找,做测试,浪费了很多时间。解决了就好,现在有时间,我就把两个函数的实现代码都贴出来,大家一看,原来如此。然后有时间,在贴一下第三个函数,去掉带有小数后面多余0的一个函数的实现,都很有用,大家可以保留,没准什么时候就能用到。
1、我们先看看获取“充值卡”原始值得Sql Server的函数吧,代码如下:
1 -- ============================================= 2 -- Author: <PatrickLiu> 3 -- Create date: <2018-11-20 18:21> 4 -- Description: <根据乱码的数据获取原始的数据> 5 -- ============================================= 6 ALTER FUNCTION [dbo].[fun_GetResidualAmount] 7 ( 8 @GarbledValue as varchar(40) 9 ) 10 RETURNS decimal(16,4) 11 AS 12 BEGIN 13 IF(@GarbledValue is null or @GarbledValue='' or @GarbledValue = '0.00') 14 BEGIN 15 RETURN 0.00; 16 END 17 18 DECLARE @TempValue varchar(40); 19 DECLARE @Length int; 20 DECLARE @Index int; 21 DECLARE @CurrentMoney decimal(16,4) 22 23 SET @TempValue=''; 24 SET @Index=1; 25 SET @Length = len(@GarbledValue) 26 27 WHILE @Index<=@Length 28 BEGIN 29 SET @TempValue = @TempValue + '' + char(ASCII(SUBSTRING(@GarbledValue,@Index,1))-((@Length-@Index-2) * 2)) 30 31 SET @Index = @Index + 1; 32 END 33 34 SET @TempValue = REVERSE(@TempValue) --字符串反转 35 IF(ISNUMERIC(@TempValue)=1) 36 SET @CurrentMoney = CAST(@TempValue as decimal(16,4)) / 10000 --转数字 37 ELSE 38 SET @CurrentMoney = 0 39 40 RETURN @CurrentMoney 41 END
2、这个函数算是生成乱码结果值的函数,功能很简单,这个就是我费力写出来的。
1 -- ============================================= 2 -- Author: <PatrickLiu> 3 -- Create date: <2018-11-20 10:32> 4 -- Description: <根据原始的数据生成乱码的数据> 5 -- ============================================= 6 ALTER FUNCTION [dbo].[fun_GetGarbledValue] 7 ( 8 @OriginalValue as decimal(16,4) 9 ) 10 RETURNS varchar(40) 11 AS 12 BEGIN 13 IF(@OriginalValue is null or @OriginalValue=0) 14 BEGIN 15 return '0'; 16 END 17 18 declare @GarbledValue varchar(40); 19 declare @length int; 20 declare @index int; 21 declare @OriginalValueCopy decimal(16,4); 22 declare @OriginalValueCopy2 varchar(40); 23 24 set @GarbledValue=''; 25 set @OriginalValueCopy2=''; 26 set @index=1; 27 set @OriginalValueCopy =@OriginalValue*10000; 28 set @OriginalValueCopy2 = REVERSE(@OriginalValueCopy); 29 set @OriginalValueCopy2='0'+SUBSTring(@OriginalValueCopy2,CHARINDEX('.',@OriginalValueCopy2),100); 30 set @length = len(@OriginalValueCopy2); 31 32 WHILE @index<=@length 33 begin 34 set @GarbledValue = @GarbledValue + '' + char(ASCII(SUBSTRING(@OriginalValueCopy2,@index,1))+((@length - @index - 2) * 2)); 35 set @index = @index + 1; 36 end 37 return @GarbledValue 38 END
3、这是第三个有用的函数,我也拿出来,给大家分享
1 -- ============================================= 2 -- Author: <PatrickLiu> 3 -- Create date: <2018-11-20 17:57> 4 -- Description: <去掉小数点后面多余的0> 5 -- ============================================= 6 CREATE FUNCTION [dbo].[fun_ClearNumberPointZero](@NumberValue varchar(50)) 7 RETURNS VARCHAR(50) 8 AS 9 BEGIN 10 DECLARE @returnValue varchar(20); 11 12 IF(@NumberValue='') 13 BEGIN 14 SET @returnValue='' --空的时候为空 15 END 16 ELSE IF(CHARINDEX('.',@NumberValue) ='0') 17 BEGIN 18 SET @returnValue=@NumberValue --针对不含小数点的 19 END 20 ELSE IF ( SUBSTRING(REVERSE(@NumberValue),PATINDEX('%[^0]%',REVERSE(@NumberValue)),1)='.') 21 BEGIN 22 SET @returnValue =left(@NumberValue,LEN(@NumberValue)-PATINDEX('%[^0]%',REVERSE(@NumberValue))) --针对小数点后全是0的 23 END 24 ELSE 25 BEGIN 26 SET @returnValue =left(@NumberValue,LEN(@NumberValue)- PATINDEX('%[^0]%.%',REVERSE(@NumberValue))+1) --其他任何情形 27 END 28 RETURN @returnValue 29 END
好了,就到这里了。对于程序员来说,解决问题是最幸福的,继续努力,每天进步一点点。
天下国家,可均也;爵禄,可辞也;白刃,可蹈也;中庸不可能也