Reputation: 33
I want to convert my string into opposite casing in sql using function. can someone help me??
I am able to do the first letter of the string but not middle letters
http://www.sql-server-helper.com/functions/initcap.aspx
Example:
input: "hI mY Name IS Joe"
output: "Hi My nAME is jOE"
Upvotes: 2
Views: 510
Reputation: 1242
Here is one of the methods to achieve this.
DECLARE @input NVARCHAR(30) = 'TesTINg PHRasE'
DECLARE @count INT = LEN(@input)
DECLARE @i INT = 1
DECLARE @val CHAR(1)
DECLARE @final VARCHAR(20)
WHILE (@i <= @count)
BEGIN
SELECT @val = SUBSTRING(@input,@i,1)
SELECT @val = CASE WHEN ASCII(@val) BETWEEN 65 AND 90 THEN LOWER(@val) ELSE UPPER(@val) END
SET @final = CONCAT(@final,@val)
SET @i = @i + 1
END
SELECT @final AS Output
Upvotes: 0
Reputation: 67311
A completely set-based approach:
DECLARE @TheLinkTable TABLE(ID INT IDENTITY,YourText NVARCHAR(1000));
INSERT INTO @TheLinkTable VALUES('hI mY Name IS Joe');
The query:
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 idea in short:
Using a tally-on-the-fly (in this case a ROW_NUMBER()
against any bigger set with a computed TOP
-clause we get a running number from 1 to n where n is the count of letters.
The second APPLY
will pick each letter separately.
The third apply will switch the casing of letters from a to z simply by XORing the binary representation and re-set the significant BIT. A blank is returned as is.
The following SELECT
will group by the ID and use a correlated sub-query to reconcatenate the string.
Another set-based approach implies a recursive 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;
You must add a WHERE to pick the last one (e.g. LEN(SwitchLetter)=LEN(YourText)
). I left it aside to show how it's working.
Upvotes: 3
Reputation: 13393
If your sql-server version support (sql-server-2017 and above), you can use TRANSLATE
function
SELECT TRANSLATE ('hI mY Name IS Joe' COLLATE Latin1_general_CS_AS
,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
Result:
Hi My nAME is jOE
Upvotes: 3