T-SQL 技巧:產生「固定長度前面補零的數字字串」

  分享到噗浪!

今天看到一則 T-SQL 語法,是用來產生固定長度前面補零的數字字串,例如你拿到一個數值為 123 而你要將其數字轉成 00000123 的字串格式,我剛看到這個語法突然楞了一下,因為看到一個我沒用過的 POWER 函式,我看到這串 T-SQL 後突然聞到一點點怪怪的味道,因此寫出了幾個不同的版本,各位可以參考參考。

以下是我今天看到的寫法:

  • 先將算出 10 的 8 次方 ( 10^8 )
  • 然後加上原本的數字 @Number
  • 運算的結果(float)轉型成 varchar(9) 字串
  • 最後從右邊算起取 8 個字元

針對效能的判斷:

  • 因為 POWER 函式把原本 int 數字型別轉型為 float 型別,較佔記憶體空間
  • 數字轉型 2 次 ( int –> float , float –> varchar )
  • 字串函式處理 1 次
DECLARE @Number INT = 123

DECLARE @Digits INT = 8

DECLARE @Result CHAR(8)

-- 第一種

SELECT @Result =
    RIGHT(
        CAST(
            POWER(10, @Digits) + @Number
            AS VARCHAR(9))
        , @Digits)


SELECT @Result

---

好奇的我我自己重寫如下:

  • 將原本的數字 @Number 轉型成 varchar(8) 後算出資料的長度 ( 注意:不能用 nvarchar 喔!! )
  • 再用 REPLICATE 函式產生特定數量的 '0'
  • 最後再加上原本的數字 @Number 轉型成 varchar(8) 後的字串

針對效能的判斷:

  • 數字轉型 2 次 ( int –> varchar )  → 若多新增一組變數可省去 1 次數值轉型的負擔
  • 數值函式處理 1 次 ( DATALENGTH )
  • 字串函式處理 1 次 ( REPLICATE )
  • 字串相加 1 次
DECLARE @Number INT = 123

DECLARE @Digits INT = 8

DECLARE @Result CHAR(8)

-- 第二種

SELECT @Result =
	REPLICATE('0', 
		@Digits - DATALENGTH(CAST(@Number AS VARCHAR(8)))) +
	CAST(@Number as VARCHAR(8))
	
SELECT @Result

---

最後我到噗浪上詢問網友的看法,果然由 Sean 提供了一個更直覺的寫法:

  • REPLICATE 函式產生固定位數 (@Digits) 的 '0'
  • 將 @Number 轉型成 varchar 字串 (不指定長度)
  • 最後從右邊算起取 8 個字元

針對效能的判斷:

  • 數字轉型 1 次 ( int –> varchar )
  • 字串函式處理 2 次 ( REPLICATE + RIGHT )
  • 字串相加 1 次
DECLARE @Number INT = 123

DECLARE @Digits INT = 8

DECLARE @Result CHAR(8)

-- 第三種

SELECT @Result =
	RIGHT(
		REPLICATE('0', @Digits) + CAST(@Number as VARCHAR)
		, @Digits)

SELECT @Result

---

我不敢說以上三種寫法哪個是好、哪個是壞,在效能上應該不會差多少,畢竟這並非頻繁執行的 T-SQL 語法,但如果以「可讀性」來看,我應該會選擇第三種寫法。

除此之外,網路上也有人(Daniel Read)提供一個寫好的 Function 可供使用,感覺也不錯,當 Function 建立好之後,只要輸入以下 T-SQL 就可以完成使命,可讀性超高! ^_^

SELECT dbo.fnPadLeft('0', 8, 123)

 

相關連結

此文章由 will 發表於 2010/5/19 下午 09:10:34

永久連結 | 評論 (5) | 此文章的RSSRSS comment feed |

分類: SQL Server

標籤: ,

評論

五月 19. 2010 22:01

FormatC

分享我的寫法

假設要輸出長度8的字串,將數字i轉成字串,同時在此字串前塞入8個0
然後直接利用Right Function 自右邊取長度8的字串出來即可

declare @i int
declare @result nvarchar(8)

Set @i = 123
Set @result = Right('00000000' + Cast(@i as nvarchar),8)

Select @result

FormatC Taiwan

五月 19. 2010 23:16

zero

我原来用left function,发现楼上的right更简洁些

zero People's Republic of China

五月 20. 2010 08:09

chuck

以前都在程式端做,原來在SQL做也很容易...

chuck Taiwan

五月 20. 2010 09:33

felix haung

第三種很真的很讚...

felix haung Taiwan

五月 20. 2010 09:51

George

我想的太簡單了: 假設位數小於 8 , 直接加上100000000 , 再取後面8碼就好了!
從沒考慮過轉型,記憶體等技術問題, 所以註定當小咖;)

declare @i int
declare @result nvarchar(8)

Set @i = 789
Set @result = Right(Cast(100000000 + @i as nvarchar),8)

Select @result

George Taiwan

新增評論


( 您輸入的Email不會顯示於網站上 )

  Country flag

biuquote
  • 評論
  • 線上預覽
Loading