In the past, when doing global search and replaces across text fields in SQL server, I’d been taking the path of least resistance and just writing ASP.NET pages to loop through and performing .Replace() on the SQL column in question.
Of course a devoted programmer, or at least one with more time on their hands, would have instead spent the time trying to find a better way to skin that cat. Well, courtesy of Google, I think I’ve found one. This article from SQLTeam.com all but handed me the answer. Since you can’t use the TSQL REPLACE function against a TEXT (or NTEXT) column the code below will work using UPDATETEXT instead:
1: /*
2: *
3: * Search & Replace
4: * Use Ctrl+Shift+M to replace template values
5: *
6: */
7:
8: set xact_abort on
9: begin tran
10:
11: declare @otxt varchar(1000)
12: set @otxt = '<string1, text, text to be replaced>'
13:
14: declare @ntxt varchar(1000)
15: set @ntxt = '<string2, text, replacing text>'
16:
17: declare @txtlen int
18: set @txtlen = len(@otxt)
19:
20: declare @ptr binary(16)
21: declare @pos int
22: declare @<string3, text, name of Unique Row ID> int
23:
24: declare curs cursor local fast_forward
25: for
26: select
27: <string3, text, name of Unique Row ID>,
28: textptr(<field_name, sysname, target text field>),
29: charindex(@otxt, <field_name, sysname, target text field>)-1
30: from
31: <table_name, sysname, target table>
32: where
33: <field_name, sysname, target text field>
34: like
35: '%' + @otxt +'%'
36:
37: open curs
38:
39: fetch next from curs into @<string3, text, name of Unique Row ID>, @ptr, @pos
40:
41: while @@fetch_status = 0
42: begin
43: print 'Text found in row id=' + cast(@<string3, text, name of Unique Row ID> as varchar) + ' at pos=' + cast(@pos as varchar)
44:
45: updatetext <table_name, sysname, target table> .<field_name, sysname, target text field> @ptr @pos @txtlen @ntxt
46:
47: fetch next from curs into @<string3, text, name of Unique Row ID>, @ptr, @pos
48: end
49:
50: close curs
51: deallocate curs
52:
53: commit tran
Of course if you compare the code above to that found in the article linked at top, you’ll notice some small discrepancies. I quickly discovered that the original code assumed that the tables unique identifier was named id. This wasn’t the case for my problem at hand and I figured that if I save this out as a SQL file, the problem will come up again so I changed every instance of "id" to be "<string3, text, name of Unique Row ID>". This little snippet of code populates the "Specifiy Values for Template Parameters" screen that pops up when you press Ctrl+Shift+M from within SQL Mangler.
One other note is that his only changes the FIRST instance of the code in any single record so it is great for doing your search and replace where there is only one instance to be replaced in one or more records. You can use this code to replace multiple instances of the search string in a single record but you’ll need to run it multiple times until the record is no longer found.
Do you have a better way of doing this? If so, let me know! Post your LEGITIMATE comment using the comment area below.
- Setting up SSL on Amazon Linux Instance under EC2 - July 26, 2018
- Method Chaining of Objects in C# - January 16, 2017
- Native SQL Backup And Restores on AWS RDS - November 9, 2016