Replace specific numbers in comma-separated list - sql

I'm trying to replace a combination of numbers using the REPLACE function in SQL Server but a specific ones inside a specific row. For example:
row value = '17,171,217,317,28' and will do it like this:
UPDATE TABLENAME SET COLUMN_NAME = REPLACE(column value,'17,','')
but that will replace all the 17 found it in the column row.
How do I specify to only replace the starting 17 found in the row?

Try using this:
UPDATE TABLENAME SET COLUMN_NAME = REPLACE(','+column value,',17,','')
Note that I agree not to store your data like that, violates 1NF (First Normal Form)

If I understand the requirement correctly:
DECLARE #ReplaceValue varchar(32) = '17,';
UPDATE dbo.TABLENAME
SET COLUMN_NAME = STUFF(COLUMN_NAME, 1, LEN(#ReplaceValue), '')
WHERE COLUMN_NAME LIKE #ReplaceValue + '%';
Example db<>fiddle

If you can fix your database design to not use comma separated lists, that is the best solution. If that is not an option, the following approach may work.
I assume that you want to remove whole values at either the start, middle, or end of the list, such as "17,171,217,317,28", "13,17,19", or "11,13,17". If the same value exists more than once, all should be removed. Example: "17,23,17,217,17" would become "23,217".
This can be done by adding extra delimiters at the start/end, replacing the delimited value (delimiter + value + delimiter) with a single delimiter, and then stripping the extra delimiters just added. If there is a chance that duplicate consecutive values may exist, existing delimiters will need to be temporarily doubled up and the replace would change to simply remove any matching (delimiter + value + delimiter) sequance.
Logic to handle all of the edge cases can get complex. The following appears to be fairly robust over a variety of test data.
DECLARE #ValueToRemove VARCHAR(100) = '17'
DECLARE #Delim VARCHAR(10) = ','
UPDATE #Data
SET UpdatedValueList =
TRIM(#Delim FROM
REPLACE(REPLACE(REPLACE(
#Delim + ValueList + #Delim -- Add leading and trailing delimiters
, #Delim, #Delim + #Delim) -- Double up delimiters
, #Delim + #ValueToRemove + #Delim, '') -- Remove value
, #Delim + #Delim, #Delim) -- Undo doubled delimiters
) -- Trim leading and trailing delimiters
Results:
ValueList
UpdatedValueList
17,171,217,317,28
171,217,317,28
13,17,19
13,19
11,13,17
11,13
17,23,17,217,17
23,217
17,18
18
16,17
16
16,17,17,18
16,18
17
16
16
The TRIM(char FROM string) syntax is available in SQL Server 2019 and later. For older versions, trimming leading and trailing delimiters gets tricky. One approach involves a STUFF/REVERSE/STUFF/REVERSE sequence, with a special case needed to handle an empty result.
UPDATE #Data
SET UpdatedValueList =
ISNULL(REVERSE(STUFF(REVERSE(STUFF(
REPLACE(REPLACE(REPLACE(
#Delim + ValueList + #Delim -- Add leading and trailing delimiters
, #Delim, #Delim + #Delim) -- Double up delimiters
, #Delim + #ValueToRemove + #Delim, '') -- Remove value
, #Delim + #Delim, #Delim) -- Undo doubled delimiters
, 1, LEN(#Delim), '')) -- Trim leading delimiter and reverse
, 1, LEN(#Delim), '')) -- Trim trailing delimiter and undo reverse
, '') -- Special case for empty result (when prior STUFF yielded null)
SELECT * FROM #Data
See this db<>fiddle for a demo.

If preserving order does not matter, you can use STRING_SPLIT() and STRING_AGG().
UPDATE #Data
SET UpdatedValueList = ISNULL((
SELECT STRING_AGG(S.Value, ',')
FROM STRING_SPLIT(ValueList, ',') S
WHERE S.Value <> #ValueToRemove
), '')
See this db<>fiddle fr a demo.
Caution. Although The examples tend to preserve order in small lists, this is not guaranteed in the function documentation. These functions are only available in SQL Server 2017 and later.

Related

Replace function in SQL Server

I have a string of data
'["Dog",,,1,"Person","2020-03-17",,4,"Todd]'
I am trying to use the replace function to replace double commas with NULL values
Solution
'["Dog",NULL,NULL,1,"Person","2020-03-17",NULL,4,"Todd]'
But I keep ending up with
'"Dog",NULL,,1,"Person","2020-03-17",NULL,4,"Todd'
(The ,,, needs to become ,NULL,NULL, but only becomes ,NULL,,)
Here is my sample code I'm using
REPLACE(FileData, ',,' , ',NULL,')
WHERE FileData LIKE '%,,%'
If you do the same replacement twice, any number of sequential commas will get handled.
REPLACE(REPLACE(FileData, ',,' , ',NULL,'), ',,' , ',NULL,')
The first REPLACE deals with all the odd positions...
',,,,,,,,'` => ',NULL,,NULL,,NULL,,NULL,'
Doing it again will deal with all of the remaining positions.
=> ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'
Note, by specifically handling a special case of three consecutive commas (as in an other answer here) you won't handle four or five or six, etc. The above solution generalises to Any length of consecutive commas.
To be fully robust, you may also need to consider when there is a missing NULL at the first or last place in the string.
[,ThatOneToMyLeft,and,ThatOneToMyRight,]
A laborious but robust approach could be to replace [, and ,] with [,, and ,,] respectively, then do the double-replacement, then undo the first steps...
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
FileData,
'[,',
'[,,'
),
',]',
',,]'
),
',,',
',NULL,'
),
',,',
',NULL,'
),
',]',
']',
),
'[,',
'['
)
There are ways to make even that less verbose, but I have to run right now :)
You can try the following:
REPLACE(REPLACE(FileData, ',,,' , ',NULL,,'), ',,' , ',NULL,')
Where FileData LIKE '%,,%'
You can create a function for your problem solving that associates to string replacement function.
Check this:
update table1
set column1 = dbo.ReplaceEx(column1, ',', 'NULL')
where column1 like '%,,%'
create function dbo.ReplaceEx(#string varchar(2000), #separator varchar(4), #nullValue varchar(10))
returns varchar(4000)
with execute as caller
as
begin
declare #result varchar(4000);
set #result = '';
select #result = concat_ws(#sep, #result,
case when rtrim(value) = '' then #nullValue
else case when ltrim(rtrim(value)) = '[' then '[' + #nullValue
else case when ltrim(rtrim(value)) = ']' then #nullValue + ']'
else value end end end
)
from string_split(#string, #separator);
return (#result);
end;

need to replace some underscores with hypens

I have a column with value
AAA_ZZZZ_7890_10_28_2014_123456.jpg
I need to replace the middle underscores so that it displays it as date i.e.
AAA_ZZZZ_7890_10-28-2014_123456.jpg
Can some one please suggest a simple update query for this.
The Number of Underscores would be same for all the values in the column but the length will vary for example some can have
AAA_q10WRQ_001_10_28_2014_12.jpg
The following should do it:
http://sqlfiddle.com/#!3/d41d8/30384/0
declare #filename varchar(64) = 'AAA_ZZZZ_7890_10_28_2014_123456.jpg'
declare #datepattern varchar(64) = '%[_][0-1][0-9][_][0-3][0-9][_][1-2][0-9][0-9][0-9][_]%'
select
filename,
substring(filename,1,datepos+2)+'-'+
substring(filename,datepos+4,2)+'-'+
substring(filename,datepos+7,1000)
from
(
select
#filename filename,
patindex(#datepattern,#filename)
as datepos
) t
;
Resulting in
AAA_ZZZZ_7890_10-28-2014_123456.jpg
Caveats to watch out for:
It is important to exactly define how you find the date. In my definition it is MM_DD_YYYY surrounded by further two underscores, and I check that the first digits of M,D,Y are 0-1,0-3,1-2 respectively (i.e. I do NOT check if month is e.g. 13.) -- of course we assume that there is only one such string in any file name.
datepos actually finds the position of the underscore before the date -- this is not an issue if taken into account in the indexing of substring.
in the 3rd substring the length cannot be NULL or infinity and I couldn't get LEN() to work in SQL Fiddle so I dirty hardcoded a large enough number (1000). Corrections to this are welcome.
Try this (assuming that the DATE portion always starts at the same character index)
declare #string varchar(64) = 'AAA_ZZZZ_7890_10_28_2014_123456.jpg'
select replace(#string, reverse(substring(reverse(#string), charindex('_', reverse(#string), 0) + 1, 10)), replace(reverse(substring(reverse(#string), charindex('_', reverse(#string), 0) + 1, 10)), '_', '-'))
If there are exactly 6 _ then for the first
select STUFF ( 'AAA_ZZZZ_7890_10_28_2014_123456.jpg' , CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', 0 ) + 1 ) + 1 ) + 1 ) , 1 , '-' )

SQL Command to replace embedded spaces with another character

I have a relational database with several fixed length character fields. I need to permanently replace all the embedded spaces with another character like - so JOHN DOE would become JOHN-DOE and ITSY BISTSY SPIDER would become ITSY-BISTSY-SPIDER. I can search before hand to make sure there are no strings that would conflict. I just need to be able to print the requested files with no embedded spaces. I would do the replacement in the C code but I want to make sure that there is never a future case where there is a JANE DOE and JANE-DOE in the DB.
By the way I have already made sure that there are no strings with more than one consecutive embedded space or leading spaces only trailing spaces to fill the fixed length fields.
Edit: thanks for all the help!
It looks like when I cut & pasted my question from Word to StackOverflow the trailing spaces got lost so the meaning my question was lost a bit.
I need to replace only the embedded spaces not the trailing spaces!
Note: I am using middle dot to stand in for spaces that don't show well.
Using:
SELECT REPLACE(operator_name, ' ', '-') FROM operator_info ;
the string JOHN·DOE············ became JOHN-DOE------------.
I need JOHN-DOE············.
I am thinking I need to use aliasing and the TRIM command but not sure how.
With whatever REPLACE function is built into your particular database.
MySQL:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_replace
Oracle:
http://psoug.org/reference/translate_replace.html
SQLServer:
http://msdn.microsoft.com/en-us/library/ms186862.aspx
Edits below based on your comment.
I've done this in SQLServer syntax so please modify the example as needed. The first example really breaks down what's going on and the second one bunches it all into a single ugly query :D
#output in this case contains your final value.
DECLARE #input VARCHAR (100) = ' some test ';
DECLARE #trimmed VARCHAR (100);
DECLARE #replaced VARCHAR (100);
DECLARE #output VARCHAR (100);
-- Get just the inner text without the preceding / trailing spaces.
SET #trimmed = LTRIM (RTRIM (#input));
-- Replace the spaces *inside* the trimmed text with a dash.
SET #replaced = REPLACE (#trimmed, ' ', '-');
-- Take the original text and replace the trimmed version (with the inner spaces) with the dash version.
SET #output = REPLACE (#input, #trimmed, #replaced);
-- Show each step of the process!
SELECT #input AS INPUT,
#trimmed AS TRIMMED,
#replaced AS REPLACED,
#output AS OUTPUT;
And as a SELECT statement.
DECLARE #inputTable TABLE (Value VARCHAR (100) NOT NULL);
INSERT INTO #inputTable (Value)
VALUES (' some test '),
(' another test ');
SELECT REPLACE (Value,
LTRIM (RTRIM (Value)),
REPLACE (LTRIM (RTRIM (Value)), ' ', '-'))
FROM #inputTable;
If you are using MSSQL:
SELECT REPLACE(field_name,' ','-');
Edit: After the requirement about skipping the trailing spaces.
You can try this one-liner:
SELECT REPLACE(RTRIM(#name), ' ', '-') + SUBSTRING(#name, LEN(RTRIM(#name)) + 1, LEN(#NAME))
However I would recommend that you put it into a user defined function instead.
assuming SQL Server:
update TABLE set column = replace (column, ' ','-')
SELECT REPLACE(field_name,' ','-');
Edit: After the requirement about skipping the trailing spaces. You can try this one-liner:
SELECT REPLACE(RTRIM(#name), ' ', '-') + SUBSTRING(#name, LEN(RTRIM(#name)) + 1;

SQL Server TRIM character

I have the following string: 'BOB*', how do I trim the * so it shows up as 'BOB'
I tried the RTRIM('BOB*','*') but does not work as says needs only 1 parameter.
Another pretty good way to implement Oracle's TRIM char FROM string in MS SQL Server is the following:
First, you need to identify a char that will never be used in your string, for example ~
You replace all spaces with that character
You replace the character * you want to trim with a space
You LTrim + RTrim the obtained string
You replace back all spaces with the trimmed character *
You replace back all never-used characters with a space
For example:
REPLACE(REPLACE(LTrim(RTrim(REPLACE(REPLACE(string,' ','~'),'*',' '))),' ','*'),'~',' ')
CREATE FUNCTION dbo.TrimCharacter
(
#Value NVARCHAR(4000),
#CharacterToTrim NVARCHAR(1)
)
RETURNS NVARCHAR(4000)
AS
BEGIN
SET #Value = LTRIM(RTRIM(#Value))
SET #Value = REVERSE(SUBSTRING(#Value, PATINDEX('%[^'+#CharacterToTrim+']%', #Value), LEN(#Value)))
SET #Value = REVERSE(SUBSTRING(#Value, PATINDEX('%[^'+#CharacterToTrim+']%', #Value), LEN(#Value)))
RETURN #Value
END
GO
--- Example
----- SELECT dbo.TrimCharacter('***BOB*********', '*')
----- returns 'BOB'
If you want to remove all asterisks then it's obvious:
SELECT REPLACE('Hello*', '*', '')
However, If you have more than one asterisk at the end and multiple throughout, but are only interested in trimming the trailing ones, then I'd use this:
DECLARE #String VarChar(50) = '**H*i****'
SELECT LEFT(#String, LEN(REPLACE(#String, '*', ' '))) --Returns: **H*i
I updated this answer to include show how to remove leading characters:
SELECT RIGHT(#String, LEN(REPLACE(REVERSE(#String), '*', ' '))) --Returns: H*i****
LEN() has a "feature" (that looks a lot like a bug) where it does not count trailing spaces.
LEFT('BOB*', LEN('BOB*')-1)
should do it.
If you wanted behavior similar to how RTRIM handles spaces i.e. that "B*O*B**" would turn into "B*O*B" without losing the embedded ones then something like -
REVERSE(SUBSTRING(REVERSE('B*O*B**'), PATINDEX('%[^*]%',REVERSE('B*O*B**')), LEN('B*O*B**') - PATINDEX('%[^*]%', REVERSE('B*O*B**')) + 1))
Should do it.
If you only want to remove a single '*' character from the value when the value ends with a '*', a simple CASE expression will do that for you:
SELECT CASE WHEN RIGHT(foo,1) = '*' THEN LEFT(foo,LEN(foo)-1) ELSE foo END AS foo
FROM (SELECT 'BOB*' AS foo)
To remove all trailing '*' characters, then you'd need a more complex expression, making use of the REVERSE, PATINDEX, LEN and LEFT functions.
NOTE: Be careful with the REPLACE function, as that will replace all occurrences of the specified character within the string, not just the trailing ones.
How about.. (in this case to trim off trailing comma or period)
For a variable:
-- Trim commas and full stops from end of City
WHILE RIGHT(#CITY, 1) IN (',', '.'))
SET #CITY = LEFT(#CITY, LEN(#CITY)-1)
For table values:
-- Trim commas and full stops from end of City
WHILE EXISTS (SELECT 1 FROM [sap_out_address] WHERE RIGHT([CITY], 1) IN (',', '.'))
UPDATE [sap_out_address]
SET [CITY] = LEFT([CITY], LEN([CITY])-1)
WHERE RIGHT([CITY], 1) IN (',', '.')
An other approach ONLY if you want to remove leading and trailing characters is the use of TRIM function.
By default removes white spaces but have te avility of remove other characters if you specify its.
SELECT TRIM('=' FROM '=SPECIALS=') AS Result;
Result
--------
SPECIALS
Unfortunately LTRIM and RTRIM does not work in the same way and only removes white spaces instead of specified characters like TRIM does if you specify its.
Reference and more examples:
https://database.guide/how-to-remove-leading-and-trailing-characters-in-sql-server/
RRIM() LTRIM() only remove spaces try http://msdn.microsoft.com/en-us/library/ms186862.aspx
Basically just replace the * with empty space
REPLACE('TextWithCharacterToReplace','CharacterToReplace','CharacterToReplaceWith')
So you want
REPLACE ('BOB*','*','')
I really like Teejay's answer, and almost stopped there. It's clever, but I got the "almost too clever" feeling, as, somehow, your string at some point will actually have a ~ (or whatever) in it on purpose. So that's not defensive enough for me to put into production.
I like Chris' too, but the PATINDEX call seems like overkill.
Though it's probably a micro-optimization, here's one without PATINDEX:
CREATE FUNCTION dbo.TRIMMIT(#stringToTrim NVARCHAR(MAX), #charToTrim NCHAR(1))
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #retVal NVARCHAR(MAX)
SET #retVal = #stringToTrim
WHILE 1 = charindex(#charToTrim, reverse(#retVal))
SET #retVal = SUBSTRING(#retVal,0,LEN(#retVal))
WHILE 1 = charindex(#charToTrim, #retVal)
SET #retVal = SUBSTRING(#retVal,2,LEN(#retVal))
RETURN #retVal
END
--select dbo.TRIMMIT('\\trim\asdfds\\\', '\')
--trim\asdfds
Returning a MAX nvarchar bugs me a little, but that's the most flexible way to do this..
I've used a similar approach to some of the above answers of using pattern matching and reversing the string to find the first non-trimmable character, then cutting that off. The difference is this version does less work than those above, so should be a little more efficient.
This creates RTRIM functionality for any specified character.
It includes an additional step set #charToFind = case... to escape the chosen character.
There is currently an issue if #charToReplace is a right crotchet (]) as there appears to be no way to escape this.
.
declare #stringToSearch nvarchar(max) = '****this is****a ** demo*****'
, #charToFind nvarchar(5) = '*'
--escape #charToFind so it doesn't break our pattern matching
set #charToFind = case #charToFind
when ']' then '[]]' --*this does not work / can't find any info on escaping right crotchet*
when '^' then '\^'
--when '%' then '%' --doesn't require escaping in this context
--when '[' then '[' --doesn't require escaping in this context
--when '_' then '_' --doesn't require escaping in this context
else #charToFind
end
select #stringToSearch
, left
(
#stringToSearch
,1
+ len(#stringToSearch)
- patindex('%[^' + #charToFind + ']%',reverse(#stringToSearch))
)
SqlServer2017 has a new way to do it: https://learn.microsoft.com/en-us/sql/t-sql/functions/trim-transact-sql?view=sql-server-2017
SELECT TRIM('0' FROM '00001900'); -> 19
SELECT TRIM( '.,! ' FROM '# test .'); -> # test
SELECT TRIM('*' FROM 'BOB*'); --> BOB
Unfortunately, RTRIM does not support trimming a specific character.
SELECT REPLACE('BOB*', '*', '')
SELECT REPLACE('B*OB*', '*', '')
-------------------------------------
Result : BOB
-------------------------------------
this will replace all asterisk* from the text
Trim with many cases
--id = 100 101 102 103 104 105 106 107 108 109 110 111
select right(id,2)+1 from ordertbl -- 1 2 3 4 5 6 7 8 9 10 11 -- last two positions are taken
select LEFT('BOB', LEN('BOB')-1) -- BO
select LEFT('BOB*',1) --B
select LEFT('BOB*',2) --BO
Try this:
Original
select replace('BOB*','*','')
Fixed to be an exact replacement
select replace('BOB*','BOB*','BOB')
Solution for one char parameter:
rtrim('0000100','0') ->
select left('0000100',len(rtrim(replace('0000100','0',' '))))
ltrim('0000100','0') ->
select right('0000100',len(replace(ltrim(replace('0000100','0',' ')),' ','.')))
#teejay solution is great. But the code below can be more understandable:
declare #X nvarchar(max)='BOB *'
set #X=replace(#X,' ','^')
set #X=replace(#X,'*',' ')
set #X= ltrim(rtrim(#X))
set #X=replace(#X,'^',' ')
Here's a function I used in the past. Note that while you can make it more general purpose by having extra parameters like the character(s) you wish to remove and what you will be replacing the space character(s) with, this greatly increases execution time. Here, I used a pipe to replace spaces AFTER pre-trimming the input. Change varchar to nvarchar if required.
CREATE FUNCTION [dbo].[TrimColons]
(
#strToTrim varchar(500)
)
RETURNS varchar(500)
AS
BEGIN
RETURN REPLACE(REPLACE(LTRIM(RTRIM(REPLACE(REPLACE(LTRIM(RTRIM(#strToTrim)),' ','|'),':',' '))),' ',':'),'|',' ')
/*
Here's a breakdown of this fancy, schmancy, trimmer
LTRIM(RTRIM(#strToTrim)) trims leading & trailing spaces first
REPLACE(LTRIM(RTRIM(#strToTrim)),' ','|') replaces inside spaces with pipe char
REPLACE(REPLACE(LTRIM(RTRIM(#strToTrim)),' ','|'),':',' ') replaces demarc character, the colon, with spaces
LTRIM(RTRIM(REPLACE(REPLACE(LTRIM(RTRIM(#strToTrim)),' ','|'),':',' '))) trims the leading & trailing converted-to-space demarc char (colon)
REPLACE(LTRIM(RTRIM(REPLACE(REPLACE(LTRIM(RTRIM(#strToTrim)),' ','|'),':',' '))),' ',':') replaces the inner space characters back to demar char (colon)
REPLACE(REPLACE(LTRIM(RTRIM(REPLACE(REPLACE(LTRIM(RTRIM(#strToTrim)),' ','|'),':',' '))),' ',':'),'|',' ') replaces the pipe characters back to original space characters
*/
END
DECLARE #String VarChar(50) = '**H*i****', #String2 VarChar(50)
--Assign to new variable #String2
;WITH X AS (
SELECT LEFT(#String, LEN(REPLACE(#String, '*', ' '))) [V1]
)
SELECT TOP 1 #String2 = RIGHT(V1, LEN(REPLACE(REVERSE(V1), '*', ' '))) FROM X
SELECT #String [#String], #String2 [#String2]
--See the intermediate values, v0 original, v1 triming end, and v2 trim the v1 leading
;WITH X AS (
SELECT #String V0, LEFT(#String, LEN(REPLACE(#String, '*', ' '))) [V1]
)
SELECT [V0], [V1], RIGHT([V1], LEN(REPLACE(REVERSE([V1]), '*', ' '))) [v2] FROM X

How can I remove leading and trailing quotes in SQL Server?

I have a table in a SQL Server database with an NTEXT column. This column may contain data that is enclosed with double quotes. When I query for this column, I want to remove these leading and trailing quotes.
For example:
"this is a test message"
should become
this is a test message
I know of the LTRIM and RTRIM functions but these workl only for spaces. Any suggestions on which functions I can use to achieve this.
I have just tested this code in MS SQL 2008 and validated it.
Remove left-most quote:
UPDATE MyTable
SET FieldName = SUBSTRING(FieldName, 2, LEN(FieldName))
WHERE LEFT(FieldName, 1) = '"'
Remove right-most quote: (Revised to avoid error from implicit type conversion to int)
UPDATE MyTable
SET FieldName = SUBSTRING(FieldName, 1, LEN(FieldName)-1)
WHERE RIGHT(FieldName, 1) = '"'
I thought this is a simpler script if you want to remove all quotes
UPDATE Table_Name
SET col_name = REPLACE(col_name, '"', '')
You can simply use the "Replace" function in SQL Server.
like this ::
select REPLACE('this is a test message','"','')
note: second parameter here is "double quotes" inside two single quotes and third parameter is simply a combination of two single quotes. The idea here is to replace the double quotes with a blank.
Very simple and easy to execute !
My solution is to use the difference in the the column values length compared the same column length but with the double quotes replaced with spaces and trimmed in order to calculate the start and length values as parameters in a SUBSTRING function.
The advantage of doing it this way is that you can remove any leading or trailing character even if it occurs multiple times whilst leaving any characters that are contained within the text.
Here is my answer with some test data:
SELECT
x AS before
,SUBSTRING(x
,LEN(x) - (LEN(LTRIM(REPLACE(x, '"', ' ')) + '|') - 1) + 1 --start_pos
,LEN(LTRIM(REPLACE(x, '"', ' '))) --length
) AS after
FROM
(
SELECT 'test' AS x UNION ALL
SELECT '"' AS x UNION ALL
SELECT '"test' AS x UNION ALL
SELECT 'test"' AS x UNION ALL
SELECT '"test"' AS x UNION ALL
SELECT '""test' AS x UNION ALL
SELECT 'test""' AS x UNION ALL
SELECT '""test""' AS x UNION ALL
SELECT '"te"st"' AS x UNION ALL
SELECT 'te"st' AS x
) a
Which produces the following results:
before after
-----------------
test test
"
"test test
test" test
"test" test
""test test
test"" test
""test"" test
"te"st" te"st
te"st te"st
One thing to note that when getting the length I only need to use LTRIM and not LTRIM and RTRIM combined, this is because the LEN function does not count trailing spaces.
I know this is an older question post, but my daughter came to me with the question, and referenced this page as having possible answers. Given that she's hunting an answer for this, it's a safe assumption others might still be as well.
All are great approaches, and as with everything there's about as many way to skin a cat as there are cats to skin.
If you're looking for a left trim and a right trim of a character or string, and your trailing character/string is uniform in length, here's my suggestion:
SELECT SUBSTRING(ColName,VAR, LEN(ColName)-VAR)
Or in this question...
SELECT SUBSTRING('"this is a test message"',2, LEN('"this is a test message"')-2)
With this, you simply adjust the SUBSTRING starting point (2), and LEN position (-2) to whatever value you need to remove from your string.
It's non-iterative and doesn't require explicit case testing and above all it's inline all of which make for a cleaner execution plan.
The following script removes quotation marks only from around the column value if table is called [Messages] and the column is called [Description].
-- If the content is in the form of "anything" (LIKE '"%"')
-- Then take the whole text without the first and last characters
-- (from the 2nd character and the LEN([Description]) - 2th character)
UPDATE [Messages]
SET [Description] = SUBSTRING([Description], 2, LEN([Description]) - 2)
WHERE [Description] LIKE '"%"'
You can use following query which worked for me-
For updating-
UPDATE table SET colName= REPLACE(LTRIM(RTRIM(REPLACE(colName, '"', ''))), '', '"') WHERE...
For selecting-
SELECT REPLACE(LTRIM(RTRIM(REPLACE(colName, '"', ''))), '', '"') FROM TableName
you could replace the quotes with an empty string...
SELECT AllRemoved = REPLACE(CAST(MyColumn AS varchar(max)), '"', ''),
LeadingAndTrailingRemoved = CASE
WHEN MyTest like '"%"' THEN SUBSTRING(Mytest, 2, LEN(CAST(MyTest AS nvarchar(max)))-2)
ELSE MyTest
END
FROM MyTable
Some UDFs for re-usability.
Left Trimming by character (any number)
CREATE FUNCTION [dbo].[LTRIMCHAR] (#Input NVARCHAR(max), #TrimChar CHAR(1) = ',')
RETURNS NVARCHAR(max)
AS
BEGIN
RETURN REPLACE(REPLACE(LTRIM(REPLACE(REPLACE(#Input,' ','¦'), #TrimChar, ' ')), ' ', #TrimChar),'¦',' ')
END
Right Trimming by character (any number)
CREATE FUNCTION [dbo].[RTRIMCHAR] (#Input NVARCHAR(max), #TrimChar CHAR(1) = ',')
RETURNS NVARCHAR(max)
AS
BEGIN
RETURN REPLACE(REPLACE(RTRIM(REPLACE(REPLACE(#Input,' ','¦'), #TrimChar, ' ')), ' ', #TrimChar),'¦',' ')
END
Note the dummy character '¦' (Alt+0166) cannot be present in the data (you may wish to test your input string, first, if unsure or use a different character).
To remove both quotes you could do this
SUBSTRING(fieldName, 2, lEN(fieldName) - 2)
you can either assign or project the resulting value
You can use TRIM('"' FROM '"this "is" a test"') which returns: this "is" a test
CREATE FUNCTION dbo.TRIM(#String VARCHAR(MAX), #Char varchar(5))
RETURNS VARCHAR(MAX)
BEGIN
RETURN SUBSTRING(#String,PATINDEX('%[^' + #Char + ' ]%',#String)
,(DATALENGTH(#String)+2 - (PATINDEX('%[^' + #Char + ' ]%'
,REVERSE(#String)) + PATINDEX('%[^' + #Char + ' ]%',#String)
)))
END
GO
Select dbo.TRIM('"this is a test message"','"')
Reference : http://raresql.com/2013/05/20/sql-server-trim-how-to-remove-leading-and-trailing-charactersspaces-from-string/
I use this:
UPDATE DataImport
SET PRIO =
CASE WHEN LEN(PRIO) < 2
THEN
(CASE PRIO WHEN '""' THEN '' ELSE PRIO END)
ELSE REPLACE(PRIO, '"' + SUBSTRING(PRIO, 2, LEN(PRIO) - 2) + '"',
SUBSTRING(PRIO, 2, LEN(PRIO) - 2))
END
Try this:
SELECT left(right(cast(SampleText as nVarchar),LEN(cast(sampleText as nVarchar))-1),LEN(cast(sampleText as nVarchar))-2)
FROM TableName