9 out of 30 rated this helpful Rate this topic

CHARINDEX (Transact-SQL)

Searches expression2 for expression1 and returns its starting position if found. The search starts at start_location.

Topic link icon Transact-SQL Syntax Conventions


CHARINDEX ( expression1 ,expression2 [ , start_location ] ) 
expression1

Is a character expression that contains the sequence to be found. expression1 is limited to 8000 characters.

expression2

Is a character expression to be searched.

start_location

Is an integer or bigint expression at which the search starts. If start_location is not specified, is a negative number, or is 0, the search starts at the beginning of expression2.

bigint if expression2 is of the varchar(max), nvarchar(max) or varbinary(max) data types; otherwise, int.

If either expression1 or expression2 is of a Unicode data type (nvarchar or nchar) and the other is not, the other is converted to a Unicode data type. CHARINDEX cannot be used with the image data type.

If either expression1 or expression2 is NULL, CHARINDEX returns NULL when the database compatibility level is 70 or higher. If the database compatibility level is 65 or lower, CHARINDEX returns NULL only when both expression1 and expression2 are NULL.

If expression1 is not found within expression2, CHARINDEX returns 0.

CHARINDEX performs comparisons based on the collation of the input. To perform a comparison in a specified collation, you can use COLLATE to apply an explicit collation to the input.

The starting position returned is 1-based, not 0-based.

The following example returns the position at which the sequence of characters bicycle starts in the DocumentSummary column of the Document table.

DECLARE @document varchar(64)

SELECT @document = 'Reflectors are vital safety' +
                   ' components of your bicycle.'
SELECT CHARINDEX('bicycle', @document)
GO

Here is the result set.

----------- 
48          

The following example uses the optional start_location parameter to start looking for vital in the fifth character of the DocumentSummary column.

DECLARE @document varchar(64)

SELECT @document = 'Reflectors are vital safety' +
                   ' components of your bicycle.'
SELECT CHARINDEX('vital', @document, 5)
GO

Here is the result set.

----------- 
16          

(1 row(s) affected)

The following example shows the result set when expression1 is not found within expression2.

DECLARE @document varchar(64)

SELECT @document = 'Reflectors are vital safety' +
                   ' components of your bicycle.'
SELECT CHARINDEX('bike', @document)
GO

Here is the result set.

----------- 
0          

(1 row(s) affected)

The following example performs a case sensitive search for the string 'TEST' in 'Das jst ein Test'.

USE tempdb;
GO
--perform a case sensitive search
SELECT CHARINDEX ( 'TEST',
       'Das ist ein Test'
       COLLATE Latin1_General_CS_AS)

Here is the result set.

----------- 
0          

The following example performs a case sensitive search for the string 'Test' in 'Das jst ein Test'.


USE tempdb;
GO
SELECT CHARINDEX ( 'Test',
       'Das ist ein Test'
       COLLATE Latin1_General_CS_AS)

Here is the result set.

----------- 
13          

The following example performs a case insensitive search for the string 'TEST' in 'Das jst ein Test'.


USE tempdb;
GO
SELECT CHARINDEX ( 'Test',
       'Das ist ein Test'
       COLLATE Latin1_General_CI_AS)
GO

Here is the result set.

----------- 
13          

Did you find this helpful?
(2000 characters remaining)
Community Content Add
Annotations FAQ
The descriptions of the first two parameters need clarified and simplified.
The descriptions of the first two parameters are unclear the way they are phrased.  I read them, and got it wrong the first time.

First Parameter: "Is a character expression that contains the sequence to be found."
Well, the string I'm searing in is truly the expression that "contains" the sequence I'm trying to find, so the way this is phrased sounds like this is the expression I'm searching it, but it's not.  This should be phrased simply as "The character expression to search for."  That way there is no room for confusion.
Second Parameter:"Is a character expression to be searched."
Again, this is phrased poorly.  There are two expressions "to be [involved in] the search", so it's not clear whether this refers to the expression "to be searched [for]" or "to be searched [within]".  This should be phrased simply as "The character expression to search within."

Finally, these suggested descriptions are not complete sentences, so the grammatical rule to not end a sentence with a preposition does not apply :)
The parameters order are wrong
As of 2012 January 24th, this documentation for SQL Server 2008 R2 states that the first argument is the text in which you want to search and that the second argument is the pattern you're looking for. This is wrong. The correct parameters order is :  $0 $0 $0the first argument is the text you want to search$0 $0the second argument the text in wich you search something$0 $0 Note that the position of the first character is 1 and not 0$0
Community Content needs cleaned up (outdated entries)
These "Community Content" entries need cleaned up or removed. Two of them point to an issue that doesn't exist anymore. The expression1 and expression2 descriptions are fine, so they were probably wrong when these comments were created but they've since been fixed.

(Incorrect -- the examples, as listed, are still incorrect. The description uses the text "jst" but the example uses the text "ist". It is also odd that someone who is not the author of a community content entry [me] is allowed to edit someone else's content)
Example for "case insensitive search" is not useful.
The example does produce the result expected, but not by doing a case insensitive search, but by performing the same case sensitive search as was provided above.

To demonstrate the search correctly, you need to use "TEST" in the CHARINDEX, and still return 13 in the result set.
Typo in example text

"The following example performs a case sensitive search for the string 'TEST' in 'Das jst ein Test'."

No, it "performs a case sensitive search for the string 'TEST' in 'Das ist ein Test'."

Hands up if...
Hands up if you counted all 48 characters in the first example
Using CHARINDEX with variables
DECLARE @a VARCHAR(5)
SET @a='l'
SELECT city,CHARINDEX(''+@a+'',city) FROM Authors

Considering we have some cities with values 'Delhi'.
Count delimited text using CHARINDEX

Since there are no split or token type functions in SQL Server, I found the need to count words in a string, ignoring leading and trailing space and ignoring consecutive spaces. This is how I did it using CHARINDEX. 
I have used a space as the delimiter here, but you can use a different, one character delimiter by setting @delim.
Remember though that the value of @word_count will be the number of sections of text delimited, NOT the number of delimiters.
I inserted extra spaces at the start, end and inbetween words in @text_to_count, to test ignoring consecutive delimiters and leading and trailing delimiters.

The output will be:

Word count = 5

DECLARE
@text_to_count as varchar(50) = ' Dr Rene Theophile   Hyacinthe Laennec  ',
@delim as varchar(1) = ' ',
@pos as int = 0,
@next_pos as int = 1,
@word_count as int = 0;
WHILE @next_pos <> 0 AND @pos < LEN(@text_to_count)
BEGIN
  SET @next_pos = CHARINDEX(@delim, @text_to_count, @pos + 1)
 
  -- Exclude consecutive delimiters
  WHILE @next_pos = @pos + 1
  BEGIN
    SET @pos = @next_pos
    SET @next_pos = CHARINDEX(@delim, @text_to_count, @pos + 1)
  END
 
  SET @word_count = @word_count + 1
  SET @pos = @next_pos
END
PRINT 'Word count = ' + CAST(@word_count as varchar(10))