Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 Dealing with null values in a cursor

Author  Topic 

statichash
Starting Member

3 Posts

Posted - 2009-07-16 : 09:16:39
I am having trouble with the values that are being returned in a cursor variable.
I have a cursor in a stored procedure that I can pass criteria data to and have the result set in the cursor variable passed back to the calling procedure. The cursor select has a right outer join so it returns a record set where some of the fields will be null. This is what I want for this particular situation.
The problem is in the calling procedure I fetch a row into local variables and then print them out to see if I get the values I want, which should be the values from running the cursor select. However, the records that contain a null value in some of the fields doesn't have values in any of the fields, even the ones that suppose to have data.

I cannot show you the code for proprietary reasons. I am declaring the cursor as forward_only static local.
This is on Sql Server 2005 Express
Has anyone seen this problem before?

webfred
Master Smack Fu Yak Hacker

8781 Posts

Posted - 2009-07-16 : 09:43:48
Is your select working with some kind of concatenating columns?
I mean col1 + ' ' + col2 or something like this.

In case of col1 OR col2 OR both having NULL values then the complete result of that concatenating will be NULL.


No, you're never too old to Yak'n'Roll if you're too young to die.
Go to Top of Page

RickD
Slow But Sure Yak Herding Master

3608 Posts

Posted - 2009-07-16 : 09:47:33
The first thing I would say is don't use a cursor unless you really, really, really have to.

forgetting that for a minute though, why not use isnull(), then you can return a blank instead (although I don't understand why you can't handle nulls, unless you are trying to do a select based on the values [in this case use AND (@Var1 = @Var1 OR Field1 = @Var1) in your where clause]).
Go to Top of Page

statichash
Starting Member

3 Posts

Posted - 2009-07-16 : 10:07:02
Ok, I have sanitized the code so there is no sensitive data.

Here is the code for the stored procedure that contains the cursor:


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: ME
-- Create date: July 16, 2009
-- Description: Gets different sets of touch point data
-- =============================================
ALTER PROCEDURE [dbo].[GetTouchPointData]
-- Add the parameters for the stored procedure here
@Country nvarchar(50) = NULL,
@Division nvarchar(50) = NULL,
@District nvarchar(50) = NULL,
@Year nvarchar(4),
@Month nvarchar(2),
@CustomerType nvarchar(50),
@TouchPointDataCursor CURSOR VARYING OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;


IF (@Country is not NULL AND @Division = '%' AND @District is NULL AND @CustomerType = 'Promoters')
BEGIN
SET @TouchPointDataCursor = CURSOR
FORWARD_ONLY STATIC FOR
SELECT main.Country Country,
op."Opportunity 1" Opportunity,
count(main.Tone) ToneCount,
main.Tone Tone,
main.Month Month,
main.Year Year,
'Promoters' "Customer Type"
FROM ( SELECT dis.Country Country,
dis.[ES/FS] [ES/FS],
tone.Tone Tone,
datepart(month,sp.date_of_survey) Month,
datepart(year,sp.date_of_survey) Year,
ovs.opportunityID opportunityID,
sp.promoters promoters
FROM [Surveyed Pop] sp INNER JOIN Districts dis
ON sp.DES1 = dis.DES1 INNER JOIN OpportunityVSurvey ovs
ON sp.ID = ovs.SurveyID INNER JOIN [Tone of Customer] tone
ON ovs.ToneID = tone.ID
WHERE ovs.ToneID = 1
AND datepart(year,sp.Date_of_Survey) = @Year
AND datepart(month,sp.Date_of_Survey) = @Month
AND (sp.tb0_10_Score Is Not Null)
AND (dis."ES/FS" LIKE @Division )
AND (dis.Country = @Country)
AND sp.Promoters = 1
) main RIGHT OUTER JOIN Opportunities op
ON main.OpportunityID = op.ID
Group By main.Country,
op."Opportunity 1",
main.Tone,
main.Month,
main.Year,
main.Promoters
Order by op."Opportunity 1";
OPEN @TouchPointDataCursor;
END
END

===============================================================
Here is the code for the stored procedure that calls the above
stored procedure:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: ME
-- Create date: July 16, 2009
-- Description: populates touchpoints table
-- =============================================
ALTER PROCEDURE [dbo].[PopulateTouchPointsTable]
-- Add the parameters for the stored procedure here

AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON

-- Insert statements for procedure here

-- Delare our variables for the returned fields
DECLARE @Country nvarchar(50), @Division nvarchar(50), @District nvarchar(50), @Opportunity nvarchar(50),
@ToneCount int, @Tone nvarchar(50), @Month nvarchar(50), @Year nvarchar(50), @CustomerType nvarchar(50)

DECLARE @MyCursor CURSOR
EXEC dbo.GetTouchPointData @Country = 'U.S.A.', @Division = '%', @Year = '2007', @Month = '06', @CustomerType = 'Promoters', @TouchPointDataCursor = @MyCursor OUTPUT
FETCH NEXT FROM @MyCursor
INTO @Country, @Opportunity, @ToneCount, @Tone, @Month, @Year, @CustomerType
WHILE (@@FETCH_STATUS = 0)
BEGIN


Print @Country + ' ' + @Opportunity + ' ' + cast(@ToneCount as nvarchar) + ' ' + @Tone + ' ' + @Month + ' ' + @Year + ' ' + @CustomerType;

FETCH NEXT FROM @MyCursor
INTO @Country, @Opportunity, @ToneCount, @Tone, @Month, @Year, @CustomerType
END
CLOSE @MyCursor
DEALLOCATE @MyCursor

END

===================================================================


Okay, if I run the select in the cursor manually I get this result set:


U.S.A. Ability to Meet Scheduling Needs 2 Positive 6 2007 Promoters
U.S.A. Effective Communications 1 Positive 6 2007 Promoters
NULL Effectiveness of Documentation 0 NULL NULL NULL Promoters
U.S.A. Effectiveness of Service 21 Positive 6 2007 Promoters
U.S.A. Employee Development 18 Positive 6 2007 Promoters
U.S.A. Pre-Call Preparation 2 Positive 6 2007 Promoters
NULL Price / Value 0 NULL NULL NULL Promoters
NULL Product Quality Reliability 0 NULL NULL NULL Promoters
U.S.A. Project Management 1 Positive 6 2007 Promoters
NULL Repaired First Attempt 0 NULL NULL NULL Promoters
U.S.A. Speed of Response 2 Positive 6 2007 Promoters

=====================================================================
But I get this result set when using the stored procedures:

Warning: Null value is eliminated by an aggregate or other SET operation.
U.S.A. Ability to Meet Scheduling Needs 2 Positive 6 2007 Promoters
U.S.A. Effective Communications 1 Positive 6 2007 Promoters

U.S.A. Effectiveness of Service 21 Positive 6 2007 Promoters
U.S.A. Employee Development 18 Positive 6 2007 Promoters
U.S.A. Pre-Call Preparation 2 Positive 6 2007 Promoters


U.S.A. Project Management 1 Positive 6 2007 Promoters

U.S.A. Speed of Response 2 Positive 6 2007 Promoters

(1 row(s) affected)

=====================================================================

The rows that have any field NULL doesn't show up at all in the result set from calling the stored procedure.
And what is that warning message about? Could that be the problem?


Go to Top of Page

statichash
Starting Member

3 Posts

Posted - 2009-07-16 : 11:03:30
I fixed it using the isnull() function on the fields in the select that would have a null value.

Consider this one resolved.

Thanks for all the input.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-07-16 : 13:25:54
seems like you can replace the called procedure with a function in which case you can use set based solution rather than cursor based approach.
Go to Top of Page
   

- Advertisement -