I want to update a string in a table - sql

I have a table, content_history with a column, doc_filename, and each row has a string value. Each string has a | and the portion in front of the | is a filepath. I want to replace that portion of the string with the correct filepath if it doesn't already match. What is the best way to go about doing this? Currently I use:
UPDATE content_history
SET doc_filename = replace (doc_filename, 'path that needs to be replaced', 'new path')
WHERE doc_filename LIKE 'old path%'
But if I don't have the exact path it doesn't replace so I have to run a select * query and manually go through and input all the different paths that are incorrect. It's not a viable long-term solution

Ideally you wouldn't store multiple values as delimited values in a single value, you should have a separate column for each distinct value, then you wouldn't be asking such a question.
You can use stuff:
set doc_filename=Stuff(doc_filename, 1, CharIndex('|', doc_filename)-1, 'new path')

you need to split value to avoid an incorrect update
update CH
set CH.doc_filename = 'new_path' + '|' + P.right_part
from content_history CH
outer apply
(
select left(CH.doc_filename, charindex('|', CH.doc_filename) - 1) as left_part
,right(CH.doc_filename, len(CH.doc_filename) - charindex('|', CH.doc_filename)) as right_part
where charindex('|', CH.doc_filename) != 0
) P
where P.left_part = 'old_path'

Related

SQL String split and update field

I have table Project with a column name Name with values in the format SYS_12345_Value. I want to update this Name field such that its value in every row is replaced by the term after second _ in its value.
At the moment it looks like SYS_82058_INDIGO and I want to replace it with INDIGO and the same for all the rows in the table.
Any help is appreciated. Thanks alot.
UPDATE : Tried #GordonLinoff's solution as follows
UPDATE Project
SET Name = (select right(str, charindex('_', reverse(str)) - 1) from (values (Name)) v(str))
WHERE Name like '%SYS%'
String manipulation in SQL Server is usually tricky. But if you want the last component, you can use:
select *,
right(str, charindex('_', reverse(str)) - 1)
from (values ('SYS_82058_INDIGO')) v(str)
Use a couple of nested CHARINDEX functions. This assumes that every row has 2 underscore (_) characters:
UPDATE dbo.YourTable
SET YourColumn = STUFF(YourColumn,1,CHARINDEX('_',YourColumn,CHARINDEX('_',YourColumn)+1),'');

Replace Function - Handling single quotes and forward slashes in SQL SERVER 2008

I want to replace some data from my database where single quotes and slashes are present.
The line below is exactly how it appears in the database and I only want to remove 'F/D', from the record.
('P/P','F/D','DFC','DTP')
Been using varations of
UPDATE tablename SET columnname = REPLACE(columnname, '''F/D,''', '')
WHERE RECORDID = XXXXX
Also been using varations of
UPDATE tablename SET columnname = REPLACE(columnname, 'F/D,', '')
WHERE RECORDID = XXXXX
Seems like it should be a simple fix but I haven't had any luck yet - all suggestions are appreciated.
The reason your's doesn't work is because you aren't including the quotes. You are looking for F/D, and 'F/D,' and your data it is 'F/D',.
If it's simply 'F/D' from all values you want removed, then you also need to remove a comma and the quotes. This method removes 'F/D' and then, any double commas (in case 'F/D' is in the middle of the string).
declare #var varchar(64) = '(''P/P'',''F/D'',''DFC'',''DTP'')'
select replace(replace(#var,'''F/D''',''),',,',',')
--update tablename
--set columnname = replace(replace(columnname,'''F/D''',''),',,',',')
--where RECORDID = 1324
If you want to replace the second element in the string, here is a way:
select
#var
--find the location of the first comma
,charindex(',',#var,0)
--find the location of the second comma
,charindex(',',#var,charindex(',',#var) + 1)
--Put it all together, using STUFF to replace the values between this range with nothing
,stuff(#var,charindex(',',#var,0),charindex(',',#var,charindex(',',#var) + 1) - charindex(',',#var,0),'')
Your first version should work fine if the comma is in the right place:
UPDATE tablename
SET columnname = REPLACE(columnname, '''F/D'',', '')
WHERE RECORDID = XXXXX;
Note that this will not replace 'F/D' if it is the first or last element in the value. If that is an issue, I would suggest that you ask another question.

stripping just the filename from a string in sql by looking at the '/' dash character

I would like to know how to accomplish getting just the file name from the below
C:\Users\avs\Desktop\Testing\Text Files\TargetFolder\PN005337.RCS
the PN005337.RCS file name can vary in name and length. However the only definitive way of capturing it would be looking at the last '\' and then bringing back any thing after the very last '\'.
Anyway to do that in sql. This is a column in sql server, but the report owner just wants to see the name.
I am doing this in SSIS so either solution would be great in an expression or in SQL.
Thank you
You could determine the index of the last slash by first REVERSE the path and then find the slash by means of CHARINDEX.
Finally you extract the filename applying to the original path the function RIGHT using the found index.
The expression would be RIGHT(path, CHARINDEX('/', REVERSE(path)) - 1)
A case for CROSS APPLY to make intermediate computations
declare #t table (full_path varchar(max));
insert #t values
('C:\Users\avs\Desktop\Testing\Text Files\TargetFolder\PN005337.RCS'),
('C:PN005337.RCS'),
('PN005337.RCS');
SELECT full_path,
CASE WHEN pback>=0 THEN RIGHT(full_path, pback)
WHEN pcol>=0 THEN RIGHT(full_path, pcol)
ELSE full_path
END as fname
FROM #t
CROSS APPLY (
SELECT pback= CHARINDEX('\', REVERSE(full_path)) -1, pCol = CHARINDEX(':', REVERSE(full_path)) -1
) pp

Update, find/replace for xml field

I have a Page table in my database.
Lets say for simplicity it has two columns; title and xmlData
It has Title something like "my example "
and I have a xml field that looks like:
<MA>
<A>
<URL>my-example-</URL>
<id>5</id>
</A>
</MA>
I am trying to do a find replace of any url that has "-" at the end, and remove the only the last trailing "-" if it exists
and remove the trailing space(if it has one, to title)
I am able to grab the rows that need to be changed by doing
select * from Pages
where title like '% '
(there is some joins and stuff, but that is basically it)
This will replace one occurrence of the URL for each row. By the look of your sample XML you have only one URL per row.
with C1 as
(
select xmlData,
xmlData.value('(/MA/A/URL/text())[1]', 'nvarchar(500)') as URL
from Pages
),
C2 as
(
select xmlData,
URL,
left(URL, len(URL) - 1) as URL2
from C1
where right(URL, 1) = '-'
)
update C2
set xmlData.modify('replace value of (/MA/A/URL/text())[1]
with sql:column("C2.URL2")')
Extract the URL value in CTE C1.
Remove the last '-' from the URL and put that in URL2 in CTE C2. Also remove the rows that does not need to be updated.
Update the XML using modify() Method (xml Data Type)
And here is another version that does the job in the XML part of the query instead.
update Pages
set xmlData.modify('replace value of (/MA/A/URL/text())[1]
with fn:substring((/MA/A/URL/text())[1], 1, fn:string-length((/MA/A/URL/text())[1])-1)')
where xmlData.exist('/MA/A/URL[fn:substring(text()[1], fn:string-length(text()[1]), 1) = "-"]') = 1
It is only possible to update one node at a time so if you have multiple URL's in in one row you have to put the code above in a loop and do the updates as long as there is something to update. You could use ##ROWCOUNT to check if the update did update anything and redo the update until ##ROWCOUNT = 0.
you can use CHARINDEX function to check if exists a character '-' and so on you can use SUBSTIRNG function to grab only part to replace of your text.
Example:
declare #a varchar(100)
set #a = 'HI, TODAY IS A - BEAUTIFUL DAY'
select
case
when charindex('-',#a) >= 0 then
substring(#a, 0, charindex('-',#a)-1) +
substring(#a, charindex('-', #a) + 1, 100)
else #a
end

Update one column from substring of another column

I have an existing column that I would like to take a subset of and insert into a second (new) column in the same table.
e.g. MyTable.[FullName] (existing column) contains a string like "P-13-146 PS - Goodyear - Tire repair"
I created a new column, MyTable.[ShortName] that I want to insert a substring of the value from the first column into ("P-13-146 PS"). The problem is that the length of the substring is different for each full name. The only real consistency is that I want up to the second whitespace character.
I am trying to resolve the following:
UPDATE [MyTable] SET [ShortName] = ???
Try this:
declare #exp varchar(200)
set #exp='P-13-146 PS - Goodyear - Tire repair'
select RTRIM(SUBSTRING(#exp,1,CHARINDEX(' ',#exp,charindex(' ',#exp)+1)))
Just combine the string manipulation functions until you get what you want:
SELECT
CASE WHEN CHARINDEX(' ',FullName, CHARINDEX(' ', FullName)+1) = 0 THEN FullName
ELSE SUBSTRING(FullName, 1, CHARINDEX(' ',FullName, CHARINDEX(' ', FullName)+1)-1)
END ShortName
FROM MyTable
The first part of the CASE statement is for names that have fewer than two spaces.