Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 

Handling The Text Data Type

By Robert Marda,

Introduction

In this article I plan to show you various ways you can manipulate the data stored in a text data type. These techniques will be particularly useful when the number of characters in the text column exceeds 8,000. They may not work when the text in row option has been set for a table. Everything I explain here will focus on manipulating columns of data type text when the text in row option is not enabled for a table. I will focus on the text data type because I am most familiar with it, although it is possible that much of what I show here will work for ntext and maybe even image data types.

This article will give you an understanding of the text data type, show you how to get the pointer for a column with data type text, how to update the value of that column using the pointer, and a few other functions that work with the text data type.

Text Data Type

Most of the functions and techniques you can use for other character data types will not work on a text data type. The data in columns of data type text are not normally stored on the same data page with the data in other columns of a table. What is stored with the other columns of a table is the pointer that tells SQL Server where it can find the characters you store in the text column. I believe this is what makes SQL Server treat the text data type differently.

You can’t concatenate characters to a text data type the way you would for a varchar column. You must first cast the text column to a varchar and then concatenate. That works fine until you have more than 8,000 characters in your text column.

You can’t use the function’s LEFT, RIGHT, or LEN on a column of data type text without casting the column as varchar(8000). Again, you will be fine unless you have more than 8,000 characters in the column. To get the length you can use the function DATALENGTH instead of LEN.

Getting A Text Pointer

The following code will get and display a pointer value:
CREATE TABLE #TestTable 
(
	RowID int,
	ColText text
)

INSERT INTO #TestTable (RowID,ColText)
SELECT 1,''

DECLARE @ptrColText varbinary(16)

SELECT @ptrColText = TEXTPTR(ColText)

FROM #TestTable

SELECT @ptrColText
The pointer must be binary(16) or varbinary(16). There must be a value for the column with data type text before a pointer will be established for it, hence the INSERT statement in the above code. The function TEXTPTR gets the pointer value for each row in a result set.

Example 1: Concatenation

The UPDATETEXT command can be used to correct spelling errors and to make any other modifications and/or additions to the characters in a column of data type text. It also works well when you need to concatenate a list that has more than 8,000 characters in it.

Here is an example that can be executed after executing the code from the previous section. This code will concatenate numbers to create a coma delimited list that is more than 8,000 characters long:
DECLARE @Value varchar(10),
	@Counter int
SET @Counter = 1

WHILE @Counter <= 2000
BEGIN
	SET @Value = LTRIM(STR(@Counter))
	IF @Counter < 2000
		SET @Value = @Value + ','
	UPDATETEXT #TestTable.ColText @ptrColText NULL 0 @Value 

	SET @Counter = @Counter + 1
END

SELECT DATALENGTH(ColText), * FROM #TestTable
Let us look at the UPDATETEXT command a moment. After the keyword UPDATETEXT you see the name of the table followed by a period and the name of the column. Next is the variable that holds the pointer. Since each text column has its own pointer this will focus on one row (and only one column) of a table no matter how many rows (and columns) are in a table.

After this you see the word NULL. This is in the position of the insert offset. When it is NULL it tells SQL Server to append the new characters to the end of all the characters currently in the text column. If the value is 0 then SQL Server will insert the new characters before all the characters currently in the text column. If you specify a number then it will count from the first character to the number specified and insert the new characters after the one found at that point.

SQL Server will not delete any characters from those in the text column unless you specify a number other than 0. In the example above I used a 0 after the NULL as the delete length to indicate I didn’t want to delete any characters from those already stored. If I had used a value other than 0 I would have gotten the following error:

Server: Msg 7135, Level 16, State 2, Line 29
Deletion length 1 is not in the range of available text, ntext, or image data.
The statement has been terminated.

Last I used a variable to supply the characters I wanted to insert into the text column.

Also you will notice that I used the function DATALENGTH in the last query to get the number of characters now stored in the column ColText. The number of characters in the column are 8,892. This number is 700 more than can be viewed in Query Analyzer since it only allows you to view the first 8,192 characters of each column. In Example 3, I will show you a way you can view those extra 700 characters.

Example 2: Misspelled Words 

The delete length parameter is useful for correcting spelling errors in a text. Here is an example that will replace a misspelled word with the word spelled correctly:
CREATE TABLE #TestTable 
(
	RowID int,
	ColText text
)

INSERT INTO #TestTable (RowID,ColText)
SELECT 1,'Here I have one mispellet word.'
UNION ALL
SELECT 2,'Here I have one mispellet word in the first sentance.  Another one is mispellet in the second sentance.'

DECLARE @ptrColText varbinary(16),
	@RowID int,
	@MisspelledWord varchar(40),
	@CorrectedWord varchar(40),
	@LenMisspelledWord int,
	@StartingPosition int

SET @RowID = 1
SET @MisspelledWord = 'mispellet'
SET @CorrectedWord = 'misspelled'
SET @LenMisspelledWord = LEN(@MisspelledWord)

PRINT 'Rows in table before correcting spelling errors.'

SELECT * FROM #TestTable WHILE @RowID <= 2
BEGIN
	SET @StartingPosition = 1
	--get pointer
	SELECT @ptrColText = TEXTPTR(ColText) FROM #TestTable WHERE RowID = @RowID

	WHILE @StartingPosition > 0
	BEGIN
		--get starting position of first occurence of characters in @MisspelledWord
		SELECT @StartingPosition = CHARINDEX(@MisspelledWord, ColText) - 1
		FROM #TestTable
		WHERE RowID = @RowID

		IF @StartingPosition > 0
			UPDATETEXT #TestTable.ColText @ptrColText @StartingPosition @LenMisspelledWord @CorrectedWord 
	END

	SET @RowID = @RowID + 1
END

PRINT 'Rows in table after correcting spelling errors.'

SELECT * FROM #TestTable

DROP TABLE #TestTable
Upon execution you will notice that the three occurrences of the word mispellet were replaced with misspelled. CHARINDEX will return a 0 when the character combination in the variable @MisspelledWord is not found in the column called ColText. Thus all occurrences will be replaced in both rows of the temp table.

Notice that in this example I used variables for the insert offset and the delete length. In the previous example these two parameters were hard coded to one value.

Example 3:  SUBSTRING

With a column of data type text it can sometimes be difficult to view the characters beyond the first 8,000 or 8,192. A varchar variable can only hold 8,000 characters. Casting the text column to varchar also will only get you the first 8,000 characters. Viewing the column in Query Analyzer will only let you see the first 8,192 characters. Enterprise Manager will display <Long Text> if there are more than 900 characters in a text field. A way to view what is beyond the first 8,192 characters can be useful. One way is to use the function SUBSTRING. Here is how this can be used on the data in the temp table from Example 1:

SELECT SUBSTRING(ColText, 8193, 700)
FROM #TestTable
The above query displays the 700 characters that you couldn’t see in Query Analyzer without using the SUBSTRING function. Using SUBSTRING you can view any section of characters stored in a column with data type text by giving the starting position number and how many characters from that point you want to see. You can use the function CHARINDEX or PATINDEX to find the desired starting point.

Conclusions

In this article you have learned how to get the pointer of a text column and how to use that pointer with the keyword UPDATETEXT to concatenate characters and replace characters in a column of data type text. You’ve also read how you can view characters stored in a column of data type text when they exceed the max normal capabilities of the tools that come with SQL Server. I have not covered every possibility. My intent in this article is to give you a starting point to develop solutions that will be helpful to you.
Total article views: 25057 | Views in the last 30 days: 21
 
Related Articles
FORUM

Add RowID Column to Bulk Insert

Add RowID Column to Bulk Insert

FORUM

RowID in Sql Server

RowID in Sql Server

FORUM

Identifying ASCII characters in NVARCHAR columns

Identifying ASCII characters in NVARCHAR columns

FORUM

[Microsoft][ODBC SQL Server Driver][SQL Server]The text, ntext, or image pointer value conflicts with the column name specified.

[Microsoft][ODBC SQL Server Driver][SQL Server]The text, ntext, or image pointer value conflicts wit...

FORUM

How to get rowid in sql server 2005

I want to get the rowid internally generated at table level in sql server.

Tags
miscellaneous    
programming    
stored procedures    
t-sql    
 
Contribute

Join the most active online SQL Server Community

SQL knowledge, delivered daily, free:

Email address:  

You make SSC a better place

As a member of SQLServerCentral, you get free access to loads of fresh content: thousands of articles and SQL scripts, a library of free eBooks, a weekly database news roundup, a great Q & A platform… And it’s our huge, buzzing community of SQL Server Professionals that makes it such a success.

Join us!

Steve Jones
Editor, SQLServerCentral.com

Already a member? Jump in:

Email address:   Password:   Remember me: Forgotten your password?
Steve Jones