T-SQL: The STUFF method, inserting characters to a varchar

There are many scenarios in which you might want to add characters to the middle of a string, for example formatting a date string from ddMMyyyy to dd/MM/yyyy (standard format in the UK).

There are also quite a few ways to do this, you can use substring and concatenation methods, or in JavaScript you could use a split, splice & join.

In SQL there is a method to do this, you might think that it would be called something nice, like splice, but no! It’s called STUFF! Granted, it does sound worse when you place an exclamation mark after it.

Anyway, this is how you would use the STUFF method using our example above.

DECLARE @strDate VARCHAR(8) = '16041980'

SELECT STUFF(STUFF(@strDate, 5, 0, '/'), 3, 0, '/') as [formattedDateString]

As you can see, we have used the STUFF method twice here, starting with the inner call, we add the ‘/’ character that is nearest the end of our string, then with the outer call, we add the second from last ‘/’ character.

It is important that we do it in this order, as we are modifying the length of the string with each call, & therefore the position of the characters after the one that we are adding.

The 5 and the 3 in the above snippet indicate the positions to insert the character, the 0’s indicate how many characters at those positions we would like to overwrite, the others are self explanatory, however if you would like it, further reference can be found here on MSDN.

T-SQL: Casting Varchar to XML removing illegal characters

As I mentioned in an earlier post, we deal a lot with XML messages on ActiveMQ JMS queues going through our ESB.  For audit purposes most data that goes through the ESB is logged at some point, including these XML messages.

These XML messages have been stored, historically, in fields of type varchar, so if we want to use XPath to query the XML, we need to cast the varchar values to XML first.

Unfortunately, there are illegal characters in our XML, so we can’t just CAST(… AS XML), we have to replace those characters first.

As I am a sharing kind of guy, here’s a snippet to help others…

Declare @cr Char(1) = char(13)
Declare @lf Char(1) = char(10)
Declare @tab Char(1) = char(9)
Declare @pound Char(1) = char(163)
Declare @uScore Char(1) = char(150)
Declare @regSymbol Char(1) = char(174)
Declare @tmSymbol Char(1) = char(153)
Declare @f1Quote Char(1) = char(146)
Declare @b1Quote Char(1) = char(145)

CAST(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE([MyXMLField], @cr, ''), @lf, ''), @tab, ''), @pound, ''), @uScore, ''),@regSymbol,''),@tmSymbol,''),@f1Quote,''),@b1Quote,'') AS XML)
FROM ...

Please let me know in the comments if you have come across a cleaner solution to this problem, or if it needs updating with extra characters.