Полностью основанный на множестве подход:
DECLARE @TheLinkTable TABLE(ID INT IDENTITY,YourText NVARCHAR(1000));
INSERT INTO @TheLinkTable VALUES('hI mY Name IS Joe');
Запрос:
WITH cte AS
(
SELECT t.ID
,t.YourText
,A.Nmbr
,C.SwitchedLetter
FROM @TheLinkTable t
CROSS APPLY(SELECT TOP(LEN(t.YourText)) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values) A(Nmbr)
CROSS APPLY(SELECT SUBSTRING(t.YourText,A.Nmbr,1)) B(TheLetter)
CROSS APPLY(SELECT CASE WHEN TheLetter LIKE '[a-zA-Z]'
THEN CHAR(ASCII(TheLetter) ^ 0x20)
ELSE CASE WHEN TheLetter=' ' THEN TheLetter END END) C(SwitchedLetter)
)
SELECT cte1.ID
,cte1.YourText
,(
SELECT SwitchedLetter AS [*]
FROM cte cte2
WHERE cte2.ID=cte1.ID
ORDER BY cte2.Nmbr
FOR XML PATH(''),TYPE).value('.','nvarchar(max)'
)
FROM cte cte1
GROUP BY cte1.ID,cte1.YourText;
Идея вкратце:
Использование подсчета-the-fly (в данном случае ROW_NUMBER()
против любого большего набора с вычисленным TOP
-классом мы получаем порядковое число от 1 до n, где n - количество букв.
Второй APPLY
выберет каждую букву отдельно.
Третье применение переключит регистр букв от a до z просто путем XOR двоичного представления и переустановит значащий бит. Возвращается пробел как есть .
Следующая SELECT
сгруппирует по идентификатору и использует коррелированный подзапрос для повторного присоединения строки.
Другой набор-Подход основан на рекурсивном CTE:
WITH recCTE AS
(
SELECT 1 AS position
,YourText
,CAST(CASE WHEN ASCII(TheLetter) BETWEEN 65 AND 90 THEN LOWER(TheLetter)
ELSE CASE WHEN ASCII(TheLetter) BETWEEN 97 AND 122 THEN UPPER(TheLetter) END END AS NVARCHAR(MAX)) AS SwitchLetter
FROM @TheLinkTable
CROSS APPLY(SELECT SUBSTRING(YourText,1,1)) A(TheLetter)
UNION ALL
SELECT r.position+1
,YourText
,CONCAT(r.SwitchLetter
,CASE WHEN ASCII(TheLetter) BETWEEN 65 AND 90 THEN LOWER(TheLetter)
ELSE CASE WHEN ASCII(TheLetter) BETWEEN 97 AND 122 THEN UPPER(TheLetter)
ELSE TheLetter END END) AS SwitchLetter
FROM recCTE r
CROSS APPLY(SELECT SUBSTRING(YourText,r.position+1,1)) A(TheLetter)
WHERE r.position<LEN(YourText)
)
SELECT * FROM recCte;
Вы должны добавить WHERE, чтобы выбрать последний (например, LEN(SwitchLetter)=LEN(YourText)
). Я оставил его в стороне, чтобы показать, как он работает.