Here's a solution that uses a UDF.
The function splits a string on a pattern as a resultset.
(similar as the STRING_SPLIT function, but with a pattern)
The FOR XML trick is then used to construct a string from the splitted parts, and to add the quotes.
DECLARE @vchNewValue VARCHAR(100), @result VARCHAR(100);
SET @vchNewValue = 'A OR B or C OR D or E OR F';
SET @result = LTRIM(RTRIM((
SELECT
CASE WHEN match = 1
THEN ' '+quotename(ltrim(rtrim(replace(value,' OR ',' or ') )),'''')+' '
ELSE UPPER(value)
END
FROM dbo.fnPattern_Split(' '+@vchNewValue+' ', ' % OR % ') AS spl
ORDER BY ordinal
FOR XML PATH(''), TYPE).value(N'./text()[1]', N'nvarchar(max)')
));
SELECT @result AS result;
| result |
| 'A or B' OR 'C or D' OR 'E or F' |
Test db<>fiddle here
The UDF
Uses PATINDEX to find each next start position of the given pattern in the string.
Then finds the nearest end position where the pattern is still valid.
So it's kinda like a lazy search in regex.
The positions are then used to insert the parts into the returned table.
CREATE FUNCTION dbo.fnPattern_Split
(
@str VARCHAR(MAX),
@pattern VARCHAR(100)
)
RETURNS @tbl TABLE (
ordinal INT,
value VARCHAR(MAX),
match BIT
)
WITH SCHEMABINDING
AS
BEGIN
DECLARE @value NVARCHAR(MAX)
, @splitvalue NVARCHAR(MAX)
, @startpos INT = 0
, @endpos INT = 0
, @ordinal INT = 0
, @foundend BIT = 0
, @patminlen INT = ISNULL(NULLIF(LEN(REPLACE(@pattern,'%','')),0),1);
WHILE (LEN(@str) > 0)
BEGIN
SET @startpos = ISNULL(NULLIF(PATINDEX('%'+@pattern+'%', @str),0), LEN(@str)+1);
IF @startpos < LEN(@str)
BEGIN
SET @foundend = 0;
SET @endpos = @startpos+@patminlen-1;
WHILE @endpos < LEN(@str) AND @foundend = 0
BEGIN
IF SUBSTRING(@str, @startpos, 1+@endpos-@startpos) LIKE @pattern
SET @foundend = 1;
ELSE
SET @endpos += 1;
END
END
ELSE SET @endpos = LEN(@str);
IF @startpos > 1
BEGIN
SET @ordinal += 1;
SET @value = LEFT(@str, @startpos-1);
INSERT INTO @tbl (ordinal, value, match)
VALUES (@ordinal, @value, 0);
END
IF @endpos >= @startpos
BEGIN
SET @ordinal += 1;
SET @splitvalue = SUBSTRING(@str, @startpos, 1+@endpos-@startpos);
INSERT INTO @tbl (ordinal, value, match)
VALUES (@ordinal, @splitvalue, 1);
END
SET @str = SUBSTRING(@str, @endpos+1, LEN(@str));
END;
RETURN;
END;