Измените регистр моих букв в строке, используя функцию sql - PullRequest
1 голос
/ 18 октября 2019

Я хочу преобразовать мою строку в противоположный регистр в SQL с помощью функции. Может ли кто-нибудь мне помочь ??

Я могу сделать первую букву строки, но не средние буквы

http://www.sql -server-helper.com / functions / initcap. aspx

Пример:

ввод: "привет, мое имя - Джо"

вывод: "привет, мое имя - jOE"

Ответы [ 2 ]

3 голосов
/ 18 октября 2019

Если ваша версия sql-сервера поддерживает (sql-server-2017 и выше), вы можете использовать TRANSLATE function

SELECT TRANSLATE ('hI mY Name IS Joe' COLLATE Latin1_general_CS_AS 
    ,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
    ,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') 

Результат:

 Hi My nAME is jOE
3 голосов
/ 18 октября 2019

Полностью основанный на множестве подход:

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)). Я оставил его в стороне, чтобы показать, как он работает.

...