SQL Split function - sql

I'm looking for a way to do this ...
SELECT FirstName, LastName, Split(AddressBlock, ' ', 1), Split(AddressBlock, ' ', 2), PostCode
FROM Contacts
The arguments I want to pass are ...
The address
The separator (current situation requires 2 spaces but this might be a comma or a space followed by a comma) or something else (it varies).
The address part I want to return (i don't always need all parts of the split result).
I seem to be able to find a few examples of splitting functions about the internet but they return a table containing the entire set of split parts.
My SQL skills aren't that great so I need the answer to be ultra simple.
I'm always working with nvarchar data and the function needs to be reusable.

If you want a user-defined function to do this, this should work. Not that pretty, but...
CREATE FUNCTION dbo.SplitStringPart (
#input nvarchar(MAX),
#separator nvarchar(10),
#index int
) RETURNS nvarchar(MAX)
BEGIN
DECLARE #counter int,
#position int,
#oldposition int,
#separatorlength int,
#result nvarchar(MAX)
SET #separatorlength = DATALENGTH(#separator) / 2
IF #separatorlength = 0 RETURN NULL
SET #result = NULL
SET #counter = 1
SET #position = -2
WHILE (#counter <= #index)
BEGIN
SET #oldposition = #position
SET #position = CHARINDEX(#separator, #input, #position + 1)
IF #position = 0 AND #counter < #index
BEGIN
SET #oldposition = 0
BREAK
END
SET #counter = #counter + 1
END
IF #oldposition = 0 AND #position = 0
RETURN NULL
ELSE IF #oldposition < 0
BEGIN
IF #position = 0 AND #index = 1
SET #result = #input
ELSE
SET #result = SUBSTRING(#input, 0, #position)
END
ELSE IF #position <= 0
SET #result = SUBSTRING(#input, #oldposition + #separatorlength, LEN(#input) - #oldposition - #separatorlength)
ELSE
SET #result = SUBSTRING(#input, #oldposition + #separatorlength, #position - #oldposition - #separatorlength)
RETURN #result
END
GO

It's not pretty, but add this to you SQL statement and it should work:
CASE
WHEN charindex(' ', substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))) > 0 THEN substring(AddressBlock, (charindex(' ', AddressBlock) + 1), charindex(' ', substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))) - 1)
ELSE substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))
END AS 'Address 1',
CASE WHEN charindex(' ', substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))) > 0 THEN substring(AddressBlock, charindex(' ', AddressBlock) + charindex(' ', substring(AddressBlock, (charindex(' ', AddressBlock) + 1), len(AddressBlock))) + 1, Len(AddressBlock))
ELSE ''
END AS 'Address 2'

Here is my version of the answer. This is MUCH faster and robust. No need to fuss around with substrings, charindex, etc.
CREATE FUNCTION [dbo].[SplitArray]
(
#RowToSplit nvarchar(MAX),
#Delimeter nvarchar(MAX)
)
RETURNS #RtnValue table (ID bigint IDENTITY, Data nvarchar(MAX))
AS
BEGIN
DECLARE #xml xml
SET #xml = '<field>' + REPLACE(#RowToSplit, #Delimeter, '</field><field>') + '</field>'
INSERT INTO #RtnValue(data)
SELECT tbl.c.value('.','nvarchar(max)')
FROM #xml.nodes('/field') tbl(c)
RETURN
END
You would simply use the resultant split values in a table, like this:
SELECT Data FROM dbo.SplitArray('this is great',' ')
This will return:
Data
============
this
is
great

Related

How to fix all caps to normal case

I have a sql table that contains an employee's full name in all caps (i.e. SMITH-EASTMAN,JIM M).
I need to be able to separate the full name into two separate columns (Last Name and First Name). This part is going well. Now I could use some assistance with removing the capital letters and putting it in normal case.
How can I take the results of my common table expression and pass them into a function?
WITH CTE AS
(
SELECT FullName = [Employee Name],
LastName = SUBSTRING([Employee Name], 1, CHARINDEX(',',[Employee Name])-1),
FirstNameStartPos = CHARINDEX(',',[Employee Name]) + 1,
MidlleInitialOrFirstNameStartPos = CHARINDEX(' ',[Employee Name]),
MiddleInitialOrSecondFirstName = SUBSTRING([Employee Name], CHARINDEX(' ',[Employee Name]),LEN([Employee Name])),
MiddleInitialOrSecondFirstNameLen = LEN(SUBSTRING([Employee Name], CHARINDEX(' ',[Employee Name]),LEN([Employee Name]))) - 1
FROM ['Med-PS PCN Mapping$']
WHERE [PS Employee ID] IS NOT NULL
),
CTE2 AS
(
SELECT FullName = CTE.FullName,
DerivedFirstName = CASE
WHEN CTE.MiddleInitialOrSecondFirstNameLen = 1
THEN SUBSTRING(CTE.FullName, CTE.FirstNameStartPos, CTE.MidlleInitialOrFirstNameStartPos - CTE.FirstNameStartPos)
ELSE SUBSTRING(CTE.FullName, CTE.FirstNameStartPos, CTE.FirstNameStartPos + CTE.MiddleInitialOrSecondFirstNameLen)
END,
DerivedLastName = CTE.LastName
FROM CTE
)
SELECT *
FROM CTE2
RESULTS
FullName DerivedFirstName DerivedLastName
SMITH-EASTMAN,JIM M JIM SMITH-EASTMAN
O'DAY,MARTIN C MARTIN O'DAY
TROUT,MADISON MARIE MADISON MARI TROUT
CREATE FUNCTION [dbo].[FixCap] ( #InputString varchar(4000) )
RETURNS VARCHAR(4000)
AS
BEGIN
DECLARE #Index INT
DECLARE #Char CHAR(1)
DECLARE #PrevChar CHAR(1)
DECLARE #OutputString VARCHAR(255)
SET #OutputString = LOWER(#InputString)
SET #Index = 1
WHILE #Index <= LEN(#InputString)
BEGIN
SET #Char = SUBSTRING(#InputString, #Index, 1)
SET #PrevChar = CASE WHEN #Index = 1 THEN ' '
ELSE SUBSTRING(#InputString, #Index - 1, 1)
END
IF #PrevChar IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&', '''', '(')
BEGIN
IF #PrevChar != '''' OR UPPER(#Char) != 'S'
SET #OutputString = STUFF(#OutputString, #Index, 1, UPPER(#Char))
END
SET #Index = #Index + 1
END
RETURN #OutputString
END
GO
select [dbo].[FixCap] (pass in DerivedFirstName from CTE2);
select [dbo].[FixCap] (pass in DerivedLastName from CTE2);
Do you want something like INITCAP ?
CREATE FUNCTION dbo.F_INITCAP (#PHRASE NVARCHAR(max))
RETURNS NVARCHAR(max)
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
IF LEN(#PHRASE) < 1 RETURN #PHRASE;
DECLARE #I INT = 1, #C CHAR(1), #P BIT = 0, #OUT VARCHAR(max) = '';
WHILE #I <= LEN(#PHRASE)
BEGIN
SET #C = SUBSTRING(#PHRASE, #I, 1);
IF #C BETWEEN 'A' AND 'Z' COLLATE Latin1_General_CI_AI
BEGIN
IF #P = 0
SET #OUT = #OUT + UPPER(#C);
ELSE
SET #OUT = #OUT + LOWER(#C);
SET #P = 1
END
ELSE
BEGIN
SET #P = 0;
SET #OUT = #OUT + LOWER(#C);
END
SET #I = #I + 1;
END
RETURN #OUT;
END
GO

Camel Case values which have special characters [duplicate]

I don't want to create a custom function for that if such function already exists in SQL Server.
Input string: This is my string to convert
Expected output: This Is My String To Convert
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[InitCap] ( #InputString varchar(4000) )
RETURNS VARCHAR(4000)
AS
BEGIN
DECLARE #Index INT
DECLARE #Char CHAR(1)
DECLARE #PrevChar CHAR(1)
DECLARE #OutputString VARCHAR(4000)
SET #OutputString = LOWER(#InputString)
SET #Index = 1
WHILE #Index <= LEN(#InputString)
BEGIN
SET #Char = SUBSTRING(#InputString, #Index, 1)
SET #PrevChar = CASE WHEN #Index = 1 THEN ' '
ELSE SUBSTRING(#InputString, #Index - 1, 1)
END
IF #PrevChar IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&', '''', '(')
SET #OutputString = STUFF(#OutputString, #Index, 1, UPPER(#Char))
SET #Index = #Index + 1
END
RETURN #OutputString
END
Declare #str nvarchar(100)
SET #str = 'my string to convert'
SELECT #str = [dbo].[InitCap](#str)
SELECT #str
AFAIK, SQL Server has no built-in function for this.
You have to write custom function for it.
Try this.
CREATE FUNCTION [dbo].[CamelCase]
(#Str varchar(8000))
RETURNS varchar(8000) AS
BEGIN
DECLARE #Result varchar(2000)
SET #Str = LOWER(#Str) + ' '
SET #Result = ''
WHILE 1=1
BEGIN
IF PATINDEX('% %',#Str) = 0 BREAK
SET #Result = #Result + UPPER(Left(#Str,1))+
SubString (#Str,2,CharIndex(' ',#Str)-1)
SET #Str = SubString(#Str,
CharIndex(' ',#Str)+1,Len(#Str))
END
SET #Result = Left(#Result,Len(#Result))
RETURN #Result
END
Output :
Input String : 'microSoft sql server'
Output String : 'Microsoft Sql Server'
I'd have to go with "No, that does not exist". This based on several years of perusing the available string-functions in T-SQL and some pretty recent 5-day courses in SQL Server 2008 R2.
Of course, I still could be wrong :).
If the goal of your operation is to prettify strings of Names then proper capitalization could be defined as the first letter of each word separated by non-alphabet characters.
Other solutions do not take into account:
Preserving spacing (especially trailing spaces).
Preserving NULL, empty-string, or a string of just spaces.
Handling more than just spaces (e.g. dashes, commas, underscores, etc...)
Handling more than one non-alpha character between words/tokens.
Handling exceptions (e.g. McDonald or III like in "James William
Bottomtooth the III").
Note: My solution does not handle exceptions.
If you are very concerned about those, then I suggest writing a CLR C# assembly for those as it will be tricky, and strings are an area where C# excels.
Another solution on here tries to account for this, but it would still take "ivan terrible the iv" and output "**IV***an Terrible The IV*".
This is the function I came up with:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fs_PascalCase]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[fs_PascalCase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fs_PascalCase]
(
#Text nVarChar(MAX)
)
RETURNS nVarChar(MAX)
AS
BEGIN
SET #Text = LOWER(#Text)--This step is optional. Keep if you want the code below to control all casing. - 11/26/2013 - MCR.
DECLARE #New nVarChar(MAX) = (CASE WHEN #Text IS NULL THEN NULL ELSE '' END)--Still return null when source is null. - 11/26/2013 - MCR.
DECLARE #Len Int = LEN(REPLACE(#Text, ' ', '_'))--If you want to count/keep trailing-spaces, you MUST use this!!! - 11/26/2013 - MCR.
DECLARE #Index Int = 1--Sql-Server is 1-based, not 0-based.
WHILE (#Index <= #Len)
IF (SUBSTRING(#Text, #Index, 1) LIKE '[^a-z]' AND #Index + 1 <= #Len)--If not alpha and there are more character(s).
SELECT #New = #New + UPPER(SUBSTRING(#Text, #Index, 2)), #Index = #Index + 2
ELSE
SELECT #New = #New + SUBSTRING(#Text, #Index, 1) , #Index = #Index + 1
--If #Text is null, then #Len will be Null, and everything will be null.
--If #Text is '', then (#Len - 1) will be -1, so ABS() it to use 1 instead, which will still return ''.
RETURN ( UPPER(LEFT(#New, 1)) + RIGHT(#New, ABS(#Len - 1)) )
END
GO
You would call it like so:
SELECT dbo.fs_PascalCase(NULL)[Null],
dbo.fs_PascalCase('')[EmptyString],
dbo.fs_PascalCase('hello how are-you TODAY ')[LongString]
The output will look like this:
My Strategy
If the name is already in mixed case, trust that it’s right.
If the name is not in mixed case, then do the following:
Trim up the name to eliminate white space
Account for the names that start with “Mc” like “McDavid”
Account for names with apostrophes like O’Reilly
Account for hyphenated names (married names) “Anderson-Johnson”
Account for multiple word names like “La Russa”
Make sure suffixes included in the names field are capitalized appropriately
The Code
Here's my original post on this: Converting String to Camel Case in SQL Server
CREATE FUNCTION [dbo].[GetCamelCaseName]
(
#Name varchar(50)
)
RETURNS VARCHAR(50) WITH SCHEMABINDING
AS
BEGIN
-- Declare the return variable here
DECLARE #NameCamelCase VARCHAR(50)
-- This is determining whether or not the name is in camel case already (if the 1st character is uppercase
-- and the third is lower (because the 2nd could be an apostrophe). To do this, you have to cast the
-- character as varbinary and compare it with the upper case of the character cast as varbinary.
IF (CAST(SUBSTRING(#Name, 1,1) as varbinary) = CAST(SUBSTRING(UPPER(#Name), 1, 1) as varbinary)
AND ((CAST(SUBSTRING(#Name, 2,1) as varbinary) = CAST(SUBSTRING(LOWER(#Name), 2, 1) as varbinary)
AND SUBSTRING(#Name, 2,1) != '''')
or
(CAST(SUBSTRING(#Name, 4,1) as varbinary) = CAST(SUBSTRING(LOWER(#Name), 4, 1) as varbinary)
AND SUBSTRING(#Name, 2,1) = '''')))
BEGIN
SELECT #NameCamelCase = RTRIM(LTRIM(#Name))
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' sr', ' Sr')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' jr', ' Jr')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' ii', ' II')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' iii', ' III')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' DE ', ' de ')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, 'macdonald', 'MacDonald')
if (#NameCamelCase LIKE '% iv') -- avoid changing "Ivan" to "IVan"
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' iv', ' IV')
if ((#NameCamelCase = 'i') or (#NameCamelCase = 'ii') or (#NameCamelCase = 'iii') or (#NameCamelCase = 'iv'))
SELECT #NameCamelCase = UPPER(#NameCamelCase)
RETURN #NameCamelCase
END
ELSE
BEGIN
SELECT #NameCamelCase = RTRIM(LTRIM(#Name))
-- "Mc-"
SELECT #NameCamelCase =
CASE
WHEN #Name LIKE 'mc%'
THEN UPPER(SUBSTRING(#Name, 1, 1)) + LOWER(SUBSTRING(#Name, 2, 1)) + UPPER(SUBSTRING(#Name, 3, 1)) + LOWER(SUBSTRING(#Name, 4, 47))
ELSE
UPPER(SUBSTRING(#Name, 1, 1)) + LOWER(SUBSTRING(#Name, 2, 49))
END
-- Apostrophes
SELECT #NameCamelCase =
CASE
WHEN #NameCamelCase LIKE '%''%'
THEN SUBSTRING(#NameCamelCase, 1, CHARINDEX('''', #NameCamelCase) - 1) + '''' + UPPER(SUBSTRING(#NameCamelCase, CHARINDEX('''', #NameCamelCase) + 1, 1)) + SUBSTRING(#NameCamelCase, CHARINDEX('''', #NameCamelCase) + 2, 50)
ELSE
#NameCamelCase
END
-- Hyphenated names (do it twice to account for double hyphens)
SELECT #NameCamelCase =
CASE
WHEN #NameCamelCase LIKE '%-%'
THEN SUBSTRING(#NameCamelCase, 1, CHARINDEX('-', #NameCamelCase) - 1) + '^' + UPPER(SUBSTRING(#NameCamelCase, CHARINDEX('-', #NameCamelCase) + 1, 1)) + SUBSTRING(#NameCamelCase, CHARINDEX('-', #NameCamelCase) + 2, 50)
ELSE
#NameCamelCase
END
SELECT #NameCamelCase =
CASE
WHEN #NameCamelCase LIKE '%-%'
THEN SUBSTRING(#NameCamelCase, 1, CHARINDEX('-', #NameCamelCase) - 1) + '^' + UPPER(SUBSTRING(#NameCamelCase, CHARINDEX('-', #NameCamelCase) + 1, 1)) + SUBSTRING(#NameCamelCase, CHARINDEX('-', #NameCamelCase) + 2, 50)
ELSE
#NameCamelCase
END
SELECT #NameCamelCase = REPLACE(#NameCamelCase, '^', '-')
-- Multiple word names (do it twice to account for three word names)
SELECT #NameCamelCase =
CASE
WHEN #NameCamelCase LIKE '% %'
THEN SUBSTRING(#NameCamelCase, 1, CHARINDEX(' ', #NameCamelCase) - 1) + '?' + UPPER(SUBSTRING(#NameCamelCase, CHARINDEX(' ', #NameCamelCase) + 1, 1)) + SUBSTRING(#NameCamelCase, CHARINDEX(' ', #NameCamelCase) + 2, 50)
ELSE
#NameCamelCase
END
SELECT #NameCamelCase =
CASE
WHEN #NameCamelCase LIKE '% %'
THEN SUBSTRING(#NameCamelCase, 1, CHARINDEX(' ', #NameCamelCase) - 1) + '?' + UPPER(SUBSTRING(#NameCamelCase, CHARINDEX(' ', #NameCamelCase) + 1, 1)) + SUBSTRING(#NameCamelCase, CHARINDEX(' ', #NameCamelCase) + 2, 50)
ELSE
#NameCamelCase
END
SELECT #NameCamelCase = REPLACE(#NameCamelCase, '?', ' ')
-- Names in Parentheses
SELECT #NameCamelCase =
CASE
WHEN #NameCamelCase LIKE '%(%'
THEN SUBSTRING(#NameCamelCase, 1, CHARINDEX('(', #NameCamelCase) - 1) + '(' + UPPER(SUBSTRING(#NameCamelCase, CHARINDEX('(', #NameCamelCase) + 1, 1)) + SUBSTRING(#NameCamelCase, CHARINDEX('(', #NameCamelCase) + 2, 50)
ELSE
#NameCamelCase
END
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' sr', ' Sr')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' jr', ' Jr')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' ii', ' II')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' iii', ' III')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' DE ', ' de ')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, 'macdonald', 'MacDonald')
if (#NameCamelCase LIKE '% iv')
SELECT #NameCamelCase = REPLACE(#NameCamelCase, ' iv', ' IV')
if ((#NameCamelCase = 'i') or (#NameCamelCase = 'ii') or (#NameCamelCase = 'iii') or (#NameCamelCase = 'iv'))
SELECT #NameCamelCase = UPPER(#NameCamelCase)
-- Return the result of the function
RETURN ISNULL(#NameCamelCase, '')
END
RETURN ISNULL(#NameCamelCase, '')
END
With SQL 2017 the function could look like this:
create function dbo.cap_words (#str varchar(max))
returns varchar(max)
as
begin
declare #result varchar(max);
select #result = string_agg( upper(left(value,1)) + substring(value,2,999),' ') from string_split(lower(#str),' ')
return #result;
end
Like me, many people may be looking for an in-query solution, query creating function, well I figured out a different approach:
SELECT REPLACE(
STUFF(
(SELECT' '+ LTRIM(RTRIM(UPPER(SUBSTRING(value, 1,1))+LOWER(SUBSTRING(value, 2, LEN(value)))))
FROM STRING_SPLIT([Message], ' ')
FOR XML PATH('')
), 1, 1, ''
), ''/*Control delimiters here*/, '') FROM [dbo].[MessageQueue]
Change [MessageQueue] table for your own table, and [Message] for your field.
The function STRING_SPLIT may require to increase your SQL compatibility level to 130.
Use the outer REPLACE function to set any delimiter you want.
Here is simple thing, don't make it complicated.
Oracle:
SELECT initcap(lower('This is MY striNg to conVerT')) FROM dual;

MSG 537 :Invalid length parameter passed to the LEFT or SUBSTRING function

when i create a function in sql server 2012 , in this function
CREATE FUNCTION howords (#str nvarchar(50), #word nvarchar(50))
RETURNS int
AS
BEGIN
DECLARE #tempstr nvarchar(max)
DECLARE #space int
DECLARE #count int
DECLARE #size int
SET #count = 0
WHILE (LEN(#str) >= 0)
BEGIN
SET #space = CHARINDEX(' ', #str, 1)
SET #tempstr = LEFT(#str, (#space - 1))
IF (#tempstr = #word)
SET #count = #count + 1
SET #size = LEN(#tempstr)
IF (((LEN(#str)) - #space) > 0)
SET #str = SUBSTRING(#str, #space + 1, ((LEN(#str)) - #space))
IF (((LEN(#str)) - #space) <= 0)
BEGIN
IF (#str = #word)
SET #count = 0
WHILE (LEN(#str) > 0)
BEGIN
SET #space = CHARINDEX(' ', #str + 1)
SET #tempstr = LEFT(#str, (#space - 1))
IF (#tempstr = #word)
SET #count = #count + 1
SET #size = LEN(#tempstr)
IF (((LEN(#str)) - #space) > 0)
SET #str = SUBSTRING(#str, #space + 1, ((LEN(#str)) - #space))
IF (((LEN(#str)) - #space) <= 0)
BEGIN
IF (#str = #word)
SET #count = #count + 1
BREAK
END
END
END
END
RETURN #count
END
when i exec this query
select dbo.howords ('hello my hello','hello' )
i want to give me count (2)
but it give me an error
MSG 537 :Invalid length parameter passed to the LEFT or SUBSTRING function.
any help?
Try this
DECLARE #tosearch VARCHAR(MAX)='Hello'
DECLARE #string VARCHAR(MAX)='hello my hello'
SELECT (DATALENGTH(#string)-DATALENGTH(REPLACE(#string,#tosearch,'')))/DATALENGTH(#tosearch)
AS OccurrenceCount

Check a chunk of text for tilde and ensure they are 60 characters apart. If not place a tilde inbetween

I currently have a function in SQL that places a tilde every 60 characters, but the original text already has tilde's so , basically I want to change that if there is a tilde and the next tilde is under 60 characters away, then skip to the next tilde. If its over 60 characters, then only then place a extra tilde.
My current function looks like;
function [dbo].[AddTilde] (
#string varchar(max),
#count int
)
returns varchar(max)
as
begin
declare #result varchar(max) = ''
declare #token varchar(max) = ''
while DATALENGTH(#string) > 0
begin
select #token = left(#string, #count)
select #string = REPLACE(#string, #token, '')
select #result +=#token +case when DATALENGTH(#string)=0 then '' else '~' end
end
return #result
end
Any help appreciated
Many Thanks
DECLARE #string1 VARCHAR(max),
#string2 VARCHAR(max) = '',
#i1 INT,
#i2 INT
SET #string1 = '12345678901234567890~1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'
WHILE LEN(#string1) > 0
BEGIN
SET #i1 = CHARINDEX('~',#string1)
SET #i2 = #i1 - (ABS(#i1-60) + (#i1-60)) / 2 -- MINIMUM OF ~ LOCATION AND 60
SET #i1 = LEN(#string1)
IF #i2 = 0 SET #i2 = #i1 - (ABS(#i1-60) + (#i1-60)) / 2 -- MINIMUM OF LENGTH OF #string1 LOCATION AND 60
IF #i2 < 60
BEGIN
SET #string2 = #string2 + LEFT(#string1,#i2)
SET #string1 = RIGHT(#string1,#i1-#i2)
END
ELSE
BEGIN
SET #string2 = #string2 + LEFT(#string1,60) + '~'
SET #string1 = RIGHT(#string1,#i1-60)
END
END
Results: 12345678901234567890~123456789012345678901234567890123456789012345678901234567890~1234567890123456789012345678901234567890
This is based on my String Splitting function, which has a very good performance.
This function should be quite efficient, albeit hard to understand (I have added a few commenets in attempt to make it easier).
You can change internal parameters easily e.g. #Delimitor can be multiple characters
Test cases are included at the bottom.
ALTER FUNCTION [dbo].[AddTilde]
(
#String VARCHAR( MAX ),
#Count INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #CurrentPosition BIGINT, #NextDelimiterPosition BIGINT, #NextFixedPosition BIGINT, #NextPosition BIGINT,
#DelimiterLength INT, #Delimiter VARCHAR( 5 ), #Result VARCHAR( MAX )
-- Initialise
SET #Delimiter = '~'
SET #DelimiterLength = LEN( #Delimiter )
SET #Result = ''
-- Ensures we can terminate loop without using an extra IF condition, saves a few = 0 checks
SET #String = #String + #Delimiter
SET #CurrentPosition = 1
-- Check for next Tilde position
SET #NextDelimiterPosition = CHARINDEX( #Delimiter, #String, #CurrentPosition )
-- Initialise fixed increment position
SET #NextFixedPosition = #Count
-- Compare, which one is earlier and use that one. Handle cases where the next token begins with Tilde
SET #NextPosition = CASE WHEN #NextDelimiterPosition - #DelimiterLength > #NextFixedPosition THEN #NextFixedPosition ELSE #NextDelimiterPosition END
WHILE #NextDelimiterPosition > 0
BEGIN
SET #Result = #Result + SUBSTRING( #String, #CurrentPosition, #NextPosition - #CurrentPosition + 1 )
-- Handle cases where the next token begins with Tilde and avoids doubling up Tildes
+ ( CASE WHEN #NextPosition = #NextDelimiterPosition THEN '' ELSE #Delimiter END )
SET #CurrentPosition = #NextPosition + 1
-- Increment fixed position
SET #NextFixedPosition = #CurrentPosition + #Count - 1
-- Check for next Tilde position
SET #NextDelimiterPosition = CHARINDEX( #Delimiter, #String, #CurrentPosition )
SET #NextPosition = CASE WHEN #NextDelimiterPosition - #DelimiterLength > #NextFixedPosition THEN #NextFixedPosition ELSE #NextDelimiterPosition END
END
-- Remove trailing Tilde
SET #Result = SUBSTRING( #Result, 1, LEN( #Result ) - #DelimiterLength )
RETURN #Result
END
/* Test Cases
SELECT dbo.[AddTilde]( 'ab~c~defghijkl~', 3 ) --> 'ab~c~def~ghi~jkl~'
SELECT dbo.[AddTilde]( '~ab~c~defghijkl', 3 ) --> '~ab~c~def~ghi~jkl'
SELECT dbo.[AddTilde]( 'ab~c~~defghijkl', 3 ) --> 'ab~c~~def~ghi~jkl'
SELECT dbo.[AddTilde]( 'abcdefghijkl', 3 ) --> 'abc~def~ghi~jkl'
SELECT dbo.[AddTilde]( 'a', 3 ) --> 'a'
*/

Remove white spaces from string and convert into title case

Here is the example which i want in output...
I have this input = "Automatic email sent"
But I want this output = "AutomaticEmailSent"
Thanks In Advance!
Use TextInfo.ToTitleCase
// Defines the string with mixed casing.
string myString = "Automatic email sent";
// Creates a TextInfo based on the "en-US" culture.
TextInfo myTI = new CultureInfo("en-US",false).TextInfo;
// Changes a string to titlecase, then replace the spaces with empty
string outputString = myTI.ToTitleCase(myString).Replace(" ", "");
Stealing a function from this answer which takes an text input and make it proper case (otherwise known as title case):
create function ProperCase(#Text as varchar(8000))
returns varchar(8000)
as
begin
declare #Reset bit;
declare #Ret varchar(8000);
declare #i int;
declare #c char(1);
select #Reset = 1, #i=1, #Ret = '';
while (#i <= len(#Text))
select #c= substring(#Text,#i,1),
#Ret = #Ret + case when #Reset=1 then UPPER(#c) else LOWER(#c) end,
#Reset = case when #c like '[a-zA-Z]' then 0 else 1 end,
#i = #i +1
return #Ret
end
Then you can combine this function with REPLACE:
SELECT REPLACE(dbo.ProperCase(column), ' ', '')
FROM MyTable
SQL Server
declare #value varchar(64) = rtrim(' ' + 'Automatic email sent')
;with t(n) as (
select n = charindex(' ', #value, 0)
union all
select n = charindex(' ', #value, n + 1)
from t
where n > 0
)
select #value = stuff(#value, n + 1, 1, upper(substring(#value, n + 1, 1))) from t where n > 0
select replace(#value, ' ', '')