[SQL Server][T-SQL]REVERSE函數輸入二進位資料時可能會失效

REVERSE是SQL字串函數的一種,可以傳回字串值的反轉順序結果,輸入值的型別可以是字串、數值還有二進位資料(Binary),最近發現反轉二進位時,偶而會失效,原因是定序(Collate),筆記問題和解決方式。

 

反轉數值、字串的順序

select reverse(1234)
select reverse('abcd')

測試通過!

 


反轉二進位資料的順序(成功)

我們輸入0x1234,希望反轉後變成0x3412

use tempdb 
select DATABASEPROPERTYEX(DB_NAME(),'collation')
declare @b varbinary(2) = 0x1234
select convert(varbinary, reverse(@b))
GO

看起來,也能成功

什麼時候會失效?經過簡單測試,發現位元組超過0x80時,都無法成功!

80 = 128 = ASCII

 


反轉二進位資料的順序(失敗及解決方式)

我們想輸入0x9E3A,希望反轉後變成3A9E。

--反轉順序失敗
use tempdb 
select DATABASEPROPERTYEX(DB_NAME(),'collation')
declare @b varbinary(2) = 0x9E3A
select convert(varbinary, reverse(@b))
GO

--反轉順序成功(換資料庫定序)
use test
select DATABASEPROPERTYEX(DB_NAME(),'collation')
declare @b varbinary(2)= 0x9E3A
select convert(varbinary, reverse(@b))
GO

--反轉順序成功(借資料表變數過一手)
use tempdb 
select DATABASEPROPERTYEX(DB_NAME(),'collation')
declare @b varbinary(2) = 0x9E3A
declare @table table(
c1 varchar(2) collate Latin1_General_BIN
)
insert into @table values(@b)
select convert(varbinary, reverse(c1)) from @table

 

執行結果:

  • 第一組是反轉失敗(資料庫定序是Chinese_Taiwan_Stroke_CI_AS),因為9E超過80。
  • 第二組改資料庫定序(Latin1_General_BIN)或是第三組過一手資料表變數,都能正確反轉順序回來。

 

0x80 是邊界

2015.10 英屬直布羅陀與西班牙邊界

 

晚上下雨,不能跑步,雨也是邊界。

 

下一篇來介紹使用系統內建函數發現的異常,進一步用sp_helptext查看程式碼後,發現是REVERSE的問題,但測試REVERSE後發現是定序問題,定序則是我們的選擇。

 


參考:

Docs REVERSE (Transact-SQL)