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後發現是定序問題,定序則是我們的選擇。
參考: