MS SQL中的移位ascii码
我想在列中添加4个值。基本上每个字符加4个ASCII数字。F.e.:MS SQL中的移位ascii码,sql,sql-server,tsql,ascii,shift,Sql,Sql Server,Tsql,Ascii,Shift,我想在列中添加4个值。基本上每个字符加4个ASCII数字。F.e.: 'ABCD' -> 'EFGH' '1234' -> '5678' 'A1B2' -> 'E5F6' 我可以像这样把所有字符都改成十六进制代码 SELECT CONVERT(VARBINARY(MAX), CONVERT(VARCHAR(MAX), Column1)) FROM Table1 但我不知道如何为每个字符添加4 可以用这个查询吗 样本: Z -> ^ z -> ~ W ->
'ABCD' -> 'EFGH'
'1234' -> '5678'
'A1B2' -> 'E5F6'
我可以像这样把所有字符都改成十六进制代码
SELECT CONVERT(VARBINARY(MAX), CONVERT(VARCHAR(MAX), Column1))
FROM Table1
但我不知道如何为每个字符添加4
可以用这个查询吗
样本:
Z -> ^
z -> ~
W -> [
9 -> =
类似于CHARASCII'z'+4=~这件事可以使用函数UDF来完成 样品
create function Charchange(@inputstring varchar(max))
returns varchar(max)
AS
BEGIN
DECLARE @i int,
@Results varchar(max)
SET @Results=''
SET @i = 1
WHILE @i <= DATALENGTH(@inputstring)
BEGIN
SET @Results = @Results + char(ASCII(SUBSTRING(@inputstring,@i,1))+4)
SET @i=@i + 1
END
RETURN @Results
END
select dbo.Charchange('abc123xyz')
or
select dbo.Charchange(coulmn1) FROM Table1
这件事可以使用函数UDF来完成 样品
create function Charchange(@inputstring varchar(max))
returns varchar(max)
AS
BEGIN
DECLARE @i int,
@Results varchar(max)
SET @Results=''
SET @i = 1
WHILE @i <= DATALENGTH(@inputstring)
BEGIN
SET @Results = @Results + char(ASCII(SUBSTRING(@inputstring,@i,1))+4)
SET @i=@i + 1
END
RETURN @Results
END
select dbo.Charchange('abc123xyz')
or
select dbo.Charchange(coulmn1) FROM Table1
我得到了递归CTE和XML路径的解决方案:
DECLARE @n int = 4 --Add 4 for each ASCII
--Here I simulate your table, hope you have ids in it
-- because I used to join it with values
;WITH YourTable AS (
SELECT CAST(SomeString as nvarchar(max)) as SomeString
FROM (VALUES ('ABCD'),('1234'),('A1B2'),('WXYZ')
) as t(SomeString)
), cte AS (--Here we replace chars
SELECT CHAR(ASCII(SUBSTRING(SomeString,1,1))+@n) as d,
1 as [level],
LEN(SomeString) as l,
SomeString as OrigString
FROM YourTable
UNION ALL
SELECT CHAR(ASCII(SUBSTRING(OrigString,[level]+1,1))+@n),
[level]+1,
l,
OrigString
FROM cte
WHERE l >= [level]+1)
--Final output
SELECT DISTINCT c.OrigString,
(SELECT d+''
FROM cte
WHERE c.OrigString = OrigString
FOR XML PATH('')
) as NewString
FROM cte c
OPTION (MAXRECURSION 0)
输出:
OrigString NewString
1234 5678
A1B2 E5F6
ABCD EFGH
WXYZ [\]^
编辑
使用VARBINARYMAX转换的解决方案:
DECLARE @x xml,
@n int = 4 --Add 4 for each ASCII
--Here I simulate your table, hope you have ids in it
-- because I used to join it with values
;WITH YourTable AS (
SELECT CAST(SomeString as nvarchar(max)) as SomeString
FROM (VALUES ('ABCD'),('1234'),('A1B2'),('WXYZ')
) as t(SomeString)
)
SELECT @x = (
SELECT CAST('<row str="'+SomeString+'"><p>'+REPLACE(REPLACE(CONVERT(nvarchar(max),CONVERT(VARBINARY(MAX),SomeString),1),'0x',''),'00','</p><p>')+'</p></row>' as xml)
FROM YourTable
FOR XML PATH('')
)
;WITH cte AS(
SELECT t.c.value('../@str','nvarchar(max)') as OrigString,
CHAR(CAST(CONVERT(VARBINARY(2),'0x'+t.c.value('.','nvarchar(2)'),1) as int)+@n) as NewValues
FROM @x.nodes('/row/p') as t(c)
)
SELECT DISTINCT
c.OrigString,
LEFT((
SELECT NewValues +''
FROM cte
WHERE OrigString = c.OrigString
FOR XML PATH('')
),LEN(c.OrigString)) as NewString
FROM cte c
相同的输出。我得到了递归CTE和XML路径的解决方案:
DECLARE @n int = 4 --Add 4 for each ASCII
--Here I simulate your table, hope you have ids in it
-- because I used to join it with values
;WITH YourTable AS (
SELECT CAST(SomeString as nvarchar(max)) as SomeString
FROM (VALUES ('ABCD'),('1234'),('A1B2'),('WXYZ')
) as t(SomeString)
), cte AS (--Here we replace chars
SELECT CHAR(ASCII(SUBSTRING(SomeString,1,1))+@n) as d,
1 as [level],
LEN(SomeString) as l,
SomeString as OrigString
FROM YourTable
UNION ALL
SELECT CHAR(ASCII(SUBSTRING(OrigString,[level]+1,1))+@n),
[level]+1,
l,
OrigString
FROM cte
WHERE l >= [level]+1)
--Final output
SELECT DISTINCT c.OrigString,
(SELECT d+''
FROM cte
WHERE c.OrigString = OrigString
FOR XML PATH('')
) as NewString
FROM cte c
OPTION (MAXRECURSION 0)
-- Sample table
declare @T table(S varchar(10));
-- Sample data
insert into @T(S) values ('ABCD'),('1234'),('A1B2'),('WXYZ');
-- Split the string using a numbers table and
-- Rebuild the string with for xml path
select T.S,
(
select char(ascii(substring(T.S, N.N, 1)) + 4)
from dbo.Number as N
where N.N >= 1 and
N.N <= len(T.S)
order by N.N
for xml path(''), type
).value('text()[1]', 'varchar(10)')
from @T as T;
输出:
OrigString NewString
1234 5678
A1B2 E5F6
ABCD EFGH
WXYZ [\]^
编辑
使用VARBINARYMAX转换的解决方案:
DECLARE @x xml,
@n int = 4 --Add 4 for each ASCII
--Here I simulate your table, hope you have ids in it
-- because I used to join it with values
;WITH YourTable AS (
SELECT CAST(SomeString as nvarchar(max)) as SomeString
FROM (VALUES ('ABCD'),('1234'),('A1B2'),('WXYZ')
) as t(SomeString)
)
SELECT @x = (
SELECT CAST('<row str="'+SomeString+'"><p>'+REPLACE(REPLACE(CONVERT(nvarchar(max),CONVERT(VARBINARY(MAX),SomeString),1),'0x',''),'00','</p><p>')+'</p></row>' as xml)
FROM YourTable
FOR XML PATH('')
)
;WITH cte AS(
SELECT t.c.value('../@str','nvarchar(max)') as OrigString,
CHAR(CAST(CONVERT(VARBINARY(2),'0x'+t.c.value('.','nvarchar(2)'),1) as int)+@n) as NewValues
FROM @x.nodes('/row/p') as t(c)
)
SELECT DISTINCT
c.OrigString,
LEFT((
SELECT NewValues +''
FROM cte
WHERE OrigString = c.OrigString
FOR XML PATH('')
),LEN(c.OrigString)) as NewString
FROM cte c
输出相同
-- Sample table
declare @T table(S varchar(10));
-- Sample data
insert into @T(S) values ('ABCD'),('1234'),('A1B2'),('WXYZ');
-- Split the string using a numbers table and
-- Rebuild the string with for xml path
select T.S,
(
select char(ascii(substring(T.S, N.N, 1)) + 4)
from dbo.Number as N
where N.N >= 1 and
N.N <= len(T.S)
order by N.N
for xml path(''), type
).value('text()[1]', 'varchar(10)')
from @T as T;
Z会发生什么?你可以编写一个函数,一个字符一个字符地遍历一个字符串,比如说,将该字符的ascii值增加4,但我认为在SQL中没有一种简单的方法可以做到这一点。W、X、Y、Z、6、7、8、9的场景是什么?Z->^,Z->~和其他特殊字符不需要考虑[,9->=,只需为每个ascii添加4个值Z发生了什么?您可以编写一个函数,逐个字符地遍历一个字符串,并将该字符的ascii值增加4,但我认为在SQL中没有一种简单的方法可以做到这一点。W、X、Y、Z、6、7、8、9?Z->^、Z->~和其他特殊字符的场景是什么不需要考虑ters->[,9->=,只需为每个ASCIY添加4个值您的解决方案启发我以更高效的方式重写答案而无需XML转换:您的解决方案启发我以更高效的方式重写答案而无需XML转换: