好久沒有寫有關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
好了,就到這里了。對於程序員來說,解決問題是最幸福的,繼續努力,每天進步一點點。
