SQLServerCentral Article

Twist in ISNULL function

,

ISNULL is a commonly used function in SQL Server used to substitute alternate value if the one being checked is “NULL”. However there is a stumbling block especially while using this function on values that are strings (CHAR/VARCHAR).

Background:

Let us consider a questionnaire report with typical questions like:-

----------------------------------

1.     What is your name?

2.     What is your age?

3.     Would you recommend our product to your friends and relatives?

4.     Did you like our services?

-----------------------------------

The underlying table for this report contains the data row wise i.e. each row holds the response for a single question. The set of questions and their answers go into the feedback table.

Sample Code to create Feedback:

CREATE TABLE Feedback (
  ProductID int,
  FeedbackQues varchar(1000),
  FeedbackAns varchar(255)
)
INSERT INTO Feedback
SELECT 1,'What is your name','Abc'
UNION
SELECT 1,'What is your age','25'
UNION
SELECT 1,'Would you recommend our product to your friends and relatives','Yes'
UNION
SELECT 1,'Did you like our services','Yes'
UNION
SELECT 1,'Was our call agent humble and helpful to you','Yes'

The report that needs to be produced should have the questions in the column headers and the responses in the data cells.

Original Report:

Agent ID

Product ID

SaleDate

What is your name?

What is your age?

Would you recommend our product to your friends and relatives?

Did you like our services?

11

A-010

17-Oct-10

Abc

45

Yes

Yes

11

A-015

17-Oct-10

Aaa

35

No

No

11

A-005

17-Oct-10

Abb

35

Yes

Yes

In order to simplify this report, let us consider alternate descriptions for the questions, which are short.

Agent ID

Product ID

SaleDate

Name

Age

Recommendation probability

Services feedback

11

A-010

17-Oct-10

Abc

45

Yes

Yes

11

A-015

17-Oct-10

Aaa

35

No

No

11

A-005

17-Oct-10

Abb

35

Yes

Yes

To achieve this, an ad-hoc mapping to the original questions can be created to store the short form of these questions.

Sample Code to create temporary mapping table:

SELECT 'What is your name' AS FeedbackQuesDesc,'Name' AS QuesSummary into #QuesMapping
UNION
SELECT 'What is your age','Age'
UNION
SELECT 'Would you recommend our product to your friends and relatives','Recommendation probability'
UNION
SELECT 'Did you like our services','Services feedback'

These questions and their responses are fed through a front end interface by the agent handling the customer. Hence, there may be a question popping up that is not there in the pre-decided list. For example:

“Was our call agent humble and helpful to you?”

The new question may not have a short description associated with it as soon as it is created.

In order to make sure that the report never resulted in a blank header (even if the short form of the question was not defined), the function ISNULL was used in the form:

ISNULL(M.QuesSummary,F.FeedbackQues)]

The query checks if the short description (QuesSummary) has no value, the actual text of the question should be returned. If not, the report should be produced with the short description.

In other words having a short description is preferred but not mandatory.

The short question from mapping table (M.QuesSummary) and in case the short form is missing the ISNULL function would display the complete original question (F.FeedbackQues).Sample code given below.

Predicament

On executing the query 

-- Selecting short question from the mapping table, 
-- if unavailable then showing the complete question from the 
-- Feedback table using the ISNULL function
SELECT 
  ISNULL(M.QuesSummary,F.FeedbackQues) AS Question,
  F.FeedbackAns AS Answer
 FROM Feedback F
   LEFT OUTER JOIN #QuesMapping M 
     ON M.FeedbackQuesDesc=F.FeedbackQues

Output expected:

Services feedback

Yes

Was our call agent humble and helpful to you

Yes

Age

25

Name

Abc

Recommendation probability

Yes

However, the actual output is not as per the expectations.

Actual output:

Services feedback

Yes

Was our call agent humble

Yes

Age

25

Name

Abc

Recommendation probability

Yes

As you can see, since no Short text was defined for the question “Was our call agent humble and helpful to you”, the expected result should have been the entire text of the question. However, the result received is truncated!

Analysis:

It seems that ISNULL function was not working the way one would expect it to.

To confirm this, let’s try a simple code to recreate the issue:-

declare @a varchar(100)
declare @b varchar(10)
set @a='My name is Ashutosh and you are reading an article on ISNULL function'
set @b=NULL
select ISNULL(@b,@a)

Output:

My name is

This confirmed that ISNULL function is type casting @a into @b returning a string equal to the length of variable @a. On checking at MSDN (http://msdn.microsoft.com/en-us/library/aa933210(v=sql.80).aspx), I read the following:

Syntax

ISNULL check_expression , replacement_value )

Arguments

check_expression

Is the expression to be checked for NULL. check_expression can be of any type.

replacement_value

Is the expression to be returned if check_expression is NULL. replacement_value must have the same type as check_expresssion..

Solution:

To resolve the issue, I type casted the check _expression in the replacement_value as shown

ISNULL(CONVERT(VARCHAR(8000),M.QuesSummary),F.FeedbackQues)

This makes the entire query look like this:

SELECT ISNULL(CONVERT(VARCHAR(8000),M.QuesSummary),F.FeedbackQues) AS Question,F.FeedbackAns AS Answer,M.QuesSummary,F.FeedbackQues
FROM Feedback F
LEFT OUTER JOIN #QuesMapping M ON M.FeedbackQuesDesc=F.FeedbackQues

Endgame:

Whenever you use ISNULL function, keep in mind the replacement_value should be of the same type and length as of the check_expression. In case they are different then explicitly type cast check_expression into replacement_value 

You can also use the COALESCE function to avoid the trap.

Rate

3.7 (149)

You rated this post out of 5. Change rating

Share

Share

Rate

3.7 (149)

You rated this post out of 5. Change rating