好久没有写有关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


      好了,就到这里了。对于程序员来说,解决问题是最幸福的,继续努力,每天进步一点点。

posted on 2018-11-21 10:07  可均可可  阅读(1779)  评论(0编辑  收藏  举报