2016-10-05 30 views
0

我想在列中移位(添加)4個值。基本上每個字符加上4個ASCII碼。 F.e:在MS SQL中移位ascii碼

'ABCD' -> 'EFGH' 
'1234' -> '5678' 
'A1B2' -> 'E5F6' 

我可以改變所有字符以這樣的十六進制代碼,

SELECT CONVERT(VARBINARY(MAX), CONVERT(VARCHAR(MAX), Column1)) 
FROM Table1 

,但我不知道如何添加4對每個字符。

查詢可以嗎?

樣品:

Z ->^
z -> ~ 
W -> [ 
9 -> = 

喜歡的東西CHAR(ASCII('z') + 4) = ~

+1

會發生什麼事'Z'? –

+0

你可以編寫一個函數逐個字符地貫穿一個字符串,也就是說,該字符的ascii值增加4,但我不認爲有一種簡單的方法可以在SQL中執行此操作。 – ZLK

+0

'W','X','Y','Z','6','7','8','9'會出現什麼情況? – Wanderer

回答

1

這個東西可以使用函數(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 @[email protected] + 1 
    END 
RETURN @Results 
END 


select dbo.Charchange('abc123xyz') 

or 

    select dbo.Charchange(coulmn1) FROM Table1 
0

我得到了解決遞歸CTE和FOR 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))[email protected]) as d, 
     1 as [level], 
     LEN(SomeString) as l, 
     SomeString as OrigString 
FROM YourTable 
UNION ALL 
SELECT CHAR(ASCII(SUBSTRING(OrigString,[level]+1,1))[email protected]), 
     [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  [\]^ 

EDIT

解VARBINARY(MAX)變換:

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)[email protected]) 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 

相同的輸出。

1
-- 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; 

SQL, Auxiliary table of numbers

Concatenate many rows into a single text string

+0

您的解決方案激發了我以更有效的方式重寫我的答案,無需XML轉換:) – gofr1