sql server编码转化:
iphone3gsB8DBB0E6 -> iphone3gs港版a b
iphone3gsB8DBB0E6 iphone3gs港版
4399D0A1D3CECFB7D4DACFDFD0A1D3CECFB7 4399小游戏在线小游戏任何方法都行~~大家都来试一试
iphone3gsB8DBB0E6 -> iphone3gs港版a b
iphone3gsB8DBB0E6 iphone3gs港版
4399D0A1D3CECFB7D4DACFDFD0A1D3CECFB7 4399小游戏在线小游戏任何方法都行~~大家都来试一试
SELECT CAST(0xB8DBB0E6 AS varchar(100))
SELECT CAST(0xD0A1D3CECFB7D4DACFDFD0A1D3CECFB7 AS varchar(100))就是简单的GBK编码而已。
关键的地方时如何区分GBK编码于其他的东西~~然后显示的时候一起显示
再转成GBK
这只能说是编码字段设计不合理。iphone3gsB8DBB0E6,究竟表示字符串“iphone3gsB8DBB0E6”,还是表示字符串“iphone3gs港版”?两种都说得通,存在歧义。人工识别的时候知道后者更有可能,是因为人可以判断“港版”比“B8DBB0E6”连接在“iphone3gs”后面更有意义,这已经加入了语义识别的成分。真的想要ASCII和非ASCII字符混合存放,就应该引入转义字符,如“iphone3gs\xb8\xdb\xb0\xe6”,这样才没有歧义。
我本意是这样:
有一个字段的内容是B8DBB0E6的话,转化成中文‘港版’,而B8DBB0E6是嵌在iphone3gsB8DBB0E6中,需要提取出来,或是转换进制。现在不知道怎么区分出来~~~
转义字符的办法可否给个例子(Tsql)~~~多谢
-------
这种混合的没办法区分按16进制可匹配出 e3 和 B8DBB0E6,显然不对,8楼说的很对,不可逆。
区分什么?你那串字符都是ASCII字符闪人
在数据库中,字符串用varchar或nvarchar存储,字节流用varbinary存储,为什么要存储形如“iphone3gsB8DBB0E6”这样的混合字串?
这个数据多半是由外部程序产生,存入数据库的。需要改进的是外部程序的编码方法。
在T-SQL中,没必要用这种自找麻烦的编码方法。
实际数据库中这是个url全地址,如下:http://www.baidu.com/s?wd=iphone+3gs+%B8%DB%B0%E6&oq=iphone+3gs+&rsp=1&f=3已经存到库里了。现想依照这个字符串,直接输出‘iphone 3gs 港版’
在库里就是混合的数据~~我也没办法~~
真要是想转的话,可以这样:DECLARE @inputstr varchar(200)
DECLARE @outputstr varchar(200)
SET @inputstr = 'iphone3gs港版'
--BEGIN: 以下部分可以定义为一个标量函数
DECLARE @tempbin varbinary(200)
DECLARE @i int
DECLARE @byte binary(1)
SET @tempbin = CAST(@inputstr AS varbinary(200))
SET @i = 1
SET @outputstr = ''
WHILE @i <= DATALENGTH(@tempbin)
BEGIN
SET @byte = SUBSTRING(@tempbin,@i,1)
IF @byte BETWEEN 0x00 AND 0x7f
SET @outputstr = @outputstr + CHAR(@byte)
ELSE
SET @outputstr = @outputstr + STUFF(sys.fn_varbintohexstr(@byte),1,1,'\')
SET @i = @i + 1
END
--END
SELECT @inputstr,@outputstr
其实这种工作在外部程序会很方便:>>> b'iphone3gs\xb8\xdb\xb0\xe6'.decode('gbk')
'iphone3gs港版'
>>> 'iphone3gs港版'.encode('gbk')
b'iphone3gs\xb8\xdb\xb0\xe6'
这种URLEncode的字串,%就是转义字符。你把它去掉了,就遗失了信息。
可以使'iphone3gs\xb8\xdb\xb0\xe6'作为输入
'iphone3gs港版'作为输出么?
>>> s = 'http://www.baidu.com/s?wd=iphone+3gs+%B8%DB%B0%E6&oq=iphone+3gs+&rsp=1&f=3'
>>> urllib.parse.unquote_to_bytes(s).decode('gbk')
'http://www.baidu.com/s?wd=iphone+3gs+港版&oq=iphone+3gs+&rsp=1&f=3'
在T-SQL中就要麻烦很多:CREATE FUNCTION dbo.hexstr2varbin(
@hexstr varchar(max)
)
RETURNS varbinary(max)
AS
/*
将表示16进制的字符串转换为2进制类型
--TESTCASES
SELECT dbo.hexstr2varbin(NULL),NULL
SELECT dbo.hexstr2varbin(''),0x
SELECT dbo.hexstr2varbin('0x'),0x
SELECT dbo.hexstr2varbin('30394161'),0x30394161
SELECT dbo.hexstr2varbin('0x30394161'),0x30394161
SELECT dbo.hexstr2varbin('0x1A2B3C4D5E6F'),0x1A2B3C4D5E6F
SELECT dbo.hexstr2varbin('0x1a2b3c4d5e6f'),0x1a2b3c4d5e6f
--UNIMPLEMENTED
SELECT dbo.hexstr2varbin('0x3039416'),0x3039416
*/
BEGIN
DECLARE @value int
DECLARE @ascii int
DECLARE @varbin varbinary(max)
IF @hexstr LIKE '0x%'
SET @hexstr = STUFF(@hexstr,1,2,'')
SET @hexstr = UPPER(@hexstr)
IF @hexstr NOT LIKE '%[^0-9A-F]%' COLLATE Chinese_PRC_BIN
BEGIN
SET @varbin = 0x
WHILE @hexstr <> ''
BEGIN
SET @value = ASCII(SUBSTRING(@hexstr,1,1))
IF @value <= 57
SET @value = @value - 48
ELSE
SET @value = @value - 55
SET @ascii = @value * 16
SET @value = ASCII(SUBSTRING(@hexstr,2,1))
IF @value <= 57
SET @value = @value - 48
ELSE
SET @value = @value - 55
SET @ascii = @ascii + @value
SET @varbin = @varbin + CAST(@ascii AS binary(1))
SET @hexstr = STUFF(@hexstr,1,2,'')
END
END
RETURN @varbin
END
GO
DECLARE @s varchar(200)
SET @s = 'http://www.baidu.com/s?wd=iphone+3gs+%B8%DB%B0%E6&oq=iphone+3gs+&rsp=1&f=3'
WHILE PATINDEX('%[%][0-9A-F][0-9A-F][%][0-9A-F][0-9A-F]%',@s) > 0
SET @s = STUFF(@s,
PATINDEX('%[%][0-9A-F][0-9A-F][%][0-9A-F][0-9A-F]%',@s),
6,
CAST(dbo.hexstr2varbin(REPLACE(SUBSTRING(@s,PATINDEX('%[%][0-9A-F][0-9A-F][%][0-9A-F][0-9A-F]%',@s),6),'%','')) AS varchar(2)))
SELECT @s