Question: I have below code:

```
declare @error varchar(max)
set @error = 'Invalid content. Error ids=[3001]'

select substring(@error, charindex('[', @error)+1, charindex(']', @error)-1)

```

I want to get number: 3001, but current result is

```
3001]

```

Anyone can explain, why still have bracket ']' ?

Answer: 
Because the third parameter of `substring` means `length of substring`, not from index to index

Reference: <https://learn.microsoft.com/en-us/sql/t-sql/functions/substring-transact-sql>

You can try this

```
select substring(@error, charindex('[', @error)+1, charindex(']', @error) - charindex('[', @error) - 1)

```
The third parameter of [SUBSTRING](https://learn.microsoft.com/en-us/sql/t-sql/functions/substring-transact-sql) is length. You are passing `charindex(']', @error)-1` which equals 32. So therefore it will gather 32 characters from the indicated starting position.

What it looks like you are trying to do is determine the length of the string between the brackets. To do this you need to subtract the index of the left bracket from the index of the right bracket. See below example.

```
declare @error varchar(max)
set @error = 'Invalid content. Error ids=[3001]'

select substring(@error, charindex('[', @error)+1, (CHARINDEX(']', @error)-1) - charindex('[', @error))

```