Include carriage returns when calculating substring - sql-server

I have some data which is stored in a VARCHAR(MAX) column that contains the control characters CR & LF (CHAR(10) & CHAR(13)).
I have some start and end position numbers that I need to use to extract a substring from the text - but when I use SUBSTRING these control characters are ignored, which results in the substring being extracted incorrectly.
I wrote a query using a CTE that replaced all instances of CRLF with another character (¬¬) and then the substring works correctly - however I need to retain the CRLFs in the text as they are used for display purposes.
Can anyone think of a way I can get the SUBSTRING function to include the control characters when it is calculating which part of the string to extract?

The SQL Server version of substring treats CRLF like other characters. For example:
select substring('123' + char(10) + char(13) + '678',1,3)
-->
123
select substring('123' + char(10) + char(13) + '678',4,2)
-->
\r\n
select substring('123' + char(10) + char(13) + '678',6,3)
-->
678
Check your code again, or post a more specific example of where substring does not work as expected.

Related

Alternatives to SQL Server QUOTENAME command without the limitation of 128 characters. How to put a string between parantheses

Is there any SQL Server function to make the same as QUOTENAME but without the limitation of 128 characters?
Now I have a string that is more than 128 characters and below function fails:
DECLARE #myString varchar(max)='''01'',''02'',''03'',''04'',''05'',''06'',''07'',''08'',''09'',''10'',''11'',''12'',''13'',''14'',''15'',''16'',''17'',''18'',''19'',''20'',''21'',''22'',''23'',''24'',''25'',''26'',''27'',''28'',''29'',''30'',''31'',''32'',''33'',''34'',''35'',''36'',''37'',''38'',''39'',''40'',''41'',''42'',''43'',''44'',''45'',''46'',''47'',''48'',''49'',''50'',''51'',''52''';
QUOTENAME(#myString, '()')
Obviously QUOTENAME fails because #myString is more than 128 characters, in this case is 260 characters length.
I want to put the string between parantheses.
Use REPLACE and wrap the value with the delimiter characters. QUOTENAME(#SomeString,'''') and N'''' + REPLACE(#SomeString,'''','''''') + N'''' would be equivalent, for example.
For yours, it would be N'(' + REPLACE(#MyString,')','))') + N')'.
SELECT QUOTENAME('Hello(There)','(') AS Quotename,
N'(' + REPLACE('Hello(There)',')','))') + N')' AS Replace;
Quotename Replace
--------------- ---------------
(Hello(There))) (Hello(There)))
Notice that for characters that have both left and right characters (such as the parenthesis (()) here) you only need to escape the right character, not the left.

Replace + (Plus) Character using a New Line

I have column which has a long string with multiple sentences. Each sentence is separated by a plus (+) character. For an example: 1. This is line one + 2. This is line two + 3. This is line Four
Now I would like to replace the plus (+) character by a new line. Using T-SQL how can I get the output like:
This is line one
This is line two
This is line three
Just use REPLACE and replace the + character with a carriage return and line break:
SELECT REPLACE(YourString,'+', CHAR(13) + CHAR(10)) AS YourString
FROM dbo.YourTable;

SQL - Replace string function is not working as intended

I have a simple string; for example,'01023201580001'.
I would like to replace the last two characters of this string; '01', with '00'.
I could extract the last two characters from this string as RIGHT(columname,2) and then use
REPLACE([columname], RIGHT([columname], 2), '00') as newColumnString
But in the result, it replaces the first two characters as well?
Expected result: 01023201580000
Result I get: 00023201580000
What am I doing wrong?
The second argument to the replace() function defines a pattern to match. The function will look for all instances of that pattern in the target string (first argument) and replace them with the replacement text (third argument).
If you know you only need to change the last two characters, you can take the value excluding those characters and then append the characters you want:
select left(columname, len(columname) - 2) + '00';
If you are doing this for an entire column and some of the rows might not end with '01', you can filter those out:
update MyTable
set columname = left(columname, len(columname) - 2) + '00'
where columname like '%01';
You could also use stuff() in a similar way.
In SQL server, you can use substring like so:
DECLARE #s NVARCHAR(20) = N'01023201580001';
DECLARE #ReplaceWith NVARCHAR(20) = N'00';
SELECT SUBSTRING(#s, 0, LEN(#s) - 1) + #ReplaceWith;
Output: 01023201580000

Removing leading and trailing commas

I am trying to find a way to remove trailing and leading commas in the SELECT statement. Here is some sample data:
SELECT
GRAIN, MATERIAL, BACKING, GRITS,
REPLACE(LTRIM(RTRIM(REPLACE(PROPERTIES, ',', ' '))), ' ', ',') PROPERTIES,
SPECIAL, APPLICATION, PRODUCTTYPE
FROM PRODUCTFINDER
I tried using trim, rtrim, and ltrim but none of them changed the strings.. Idk if I was using the wrong syntax or what, but could someone help me please?
I am using SQL Server 2008.
Just another option.
This is a non-destructive approach that will eliminate any number of repeating commas and forces a final cleanup via the double pipes
For the expansion,reduction, and elimination I picked two obscure characters †‡
Example
Declare #S varchar(max) =',,,,Some,,,,,Content,,,'
Select
replace(
replace(
replace(
replace(
replace('||,' + #S + ',||', ',', '†‡'),
'‡†', ''
),
'†‡', ','
),
'||,', ''
),
',||', ''
)
Returns
Some,Content
EDIT - Removed the LTRIM()/RTRIM()
Try this:
SELECT
GRAIN, MATERIAL, BACKING, GRITS,
TRIM(',' FROM PRODUCTFINDER.PROPERTIES) AS PROPERTIES,
TRIM(',' FROM PRODUCTFINDER.SPECIAL) AS SPECIAL,
TRIM(',' FROM PRODUCTFINDER.APPLICATION) AS APPLICATION,
TRIM(',' FROM PRODUCTFINDER.PRODUCTTYPE) AS PRODUCTTYPE
FROM PRODUCTFINDER
I am not sure which columns you want to trim.
This variant of TRIM (Transact-SQL) is available since SQL-Server 2017.
If you have an earlier version of SQL-Server, do this in the Font-End (VB). This also gives you the possibility to replace multiple commas by single ones in the middle of the text.
Dim s = ",,,Abc,,,Def,Xyz,,,"
Console.WriteLine(Regex.Replace(s, ",{2,}", ",").Trim(","c))
Prints
Abc,Def,Xyz
Regex.Replace(s, ",{2,}", ",") uses the a regular expression ,{2,} to find 2 or more occurrences of commas and replaces them by one single comma. .Trim(","c) removes leading and trailing commas.
For Regex you need a
Imports System.Text.RegularExpressions
Another variant uses string split with the RemoveEmptyEntries option and then joins the parts again to form the result.
Dim s = ",,,Abc,,,Def,Xyz,,,"
Dim parts As String() = s.Split(New Char() {","c}, StringSplitOptions.RemoveEmptyEntries)
Console.WriteLine(String.Join(",", parts))
Here's one method using PATINDEX with LEFT and RIGHT.
declare #var varchar(64)= ',,,,,,,,asdf,dsf,sdfsd,asdf,,,,,,,,'
select
left(right(#var,len(#var) - patindex('%[^,]%',#var) + 1)
,len(right(#var,len(#var) - patindex('%[^,]%',#var) + 1)) - patindex('%[^,]%',reverse(right(#var,len(#var) - patindex('%[^,]%',#var) + 1))) + 1)
Just change #var to your column name.
This code strips the leading commas by searching for the first value that isn't a comma, via patindex('%[^,]%',#var) and takes everything to the RIGHT of this character. Then, we do the same thing using LEFT to remove the trailing commas.
select
Special = left(right(Special,len(Special) - patindex('%[^,]%',Special) + 1),len(right(Special,len(Special) - patindex('%[^,]%',Special) + 1)) - patindex('%[^,]%',reverse(right(Special,len(Special) - patindex('%[^,]%',Special) + 1))) + 1)
,[Application] = left(right([Application],len([Application]) - patindex('%[^,]%',[Application]) + 1),len(right([Application],len([Application]) - patindex('%[^,]%',[Application]) + 1)) - patindex('%[^,]%',reverse(right([Application],len([Application]) - patindex('%[^,]%',[Application]) + 1))) + 1)
,[ProductType] = left(right([ProductType],len([ProductType]) - patindex('%[^,]%',[ProductType]) + 1),len(right([ProductType],len([ProductType]) - patindex('%[^,]%',[ProductType]) + 1)) - patindex('%[^,]%',reverse(right([ProductType],len([ProductType]) - patindex('%[^,]%',[ProductType]) + 1))) + 1)
FROM PRODUCTFINDER
SQL Server is not ideal place for manipulating strings so trim logic should be at programming level
As far as trimming particular character is required in query, refer to below thread
Trimming any Leading or trailing characters

Check if a string contains a substring in SQL Server 2005, using a stored procedure

I've a string, #mainString = 'CATCH ME IF YOU CAN'. I want to check whether the word ME is inside #mainString.
How do I check if a string has a specific substring in SQL?
CHARINDEX() searches for a substring within a larger string, and returns the position of the match, or 0 if no match is found
if CHARINDEX('ME',#mainString) > 0
begin
--do something
end
Edit or from daniels answer, if you're wanting to find a word (and not subcomponents of words), your CHARINDEX call would look like:
CHARINDEX(' ME ',' ' + REPLACE(REPLACE(#mainString,',',' '),'.',' ') + ' ')
(Add more recursive REPLACE() calls for any other punctuation that may occur)
You can just use wildcards in the predicate (after IF, WHERE or ON):
#mainstring LIKE '%' + #substring + '%'
or in this specific case
' ' + #mainstring + ' ' LIKE '% ME[., ]%'
(Put the spaces in the quoted string if you're looking for the whole word, or leave them out if ME can be part of a bigger word).

Resources