Showing posts with label tsql. Show all posts
Showing posts with label tsql. Show all posts

Friday, March 30, 2012

HELP!! - TSQL Cursor problem

Hi,

I have a work project due very soon and am stuck with something.

I am using a cursor in a stored procedure to return the required data for output in an ASP/VBScript page. The problem is that (as run in MS Query Analyser) the stored procedure returns the data in individual data sets - 1 for each iteration of the cursor. It is returned in multiple frames in QA, the same as when you run multiple queries at the same time in the QA window.

I have never used cursors before so maybe this is to be expected - but what I want is for all the data to be returned in one data set. At present I can only access part of the data in my webpage - when I run the stored procedure and loop thru the data in the webpage, there is only the data from the first iteration of the cursor.

Below is a representation of a chunk of rows from the table, the stored procedure and a representation of the returned results. Can you please help me to return all the data in a single data set, or else tell me how I can access each of the data sets in my webpage.

Many thanks in advance for your help

Simon

simon.barnettnospam@.elexon.co.uk

Table

ID_col, Category_col, KeyAccountability_col, PerformanceMeasure_col, StaffID_col
1, Delivery, KeyAcc1, PerfMeas1, 3
3, Delivery, KeyAcc2, PerfMeas2, 3
7, Delivery, KeyAcc3, PerfMeas3, 3
8, Department, KeyAcc4, PerfMeas4, 3
11, Department, KeyAcc5, PerfMeas5, 3
12, Department, KeyAcc6, PerfMeas6, 3
13, Communications, KeyAcc7, PerfMeas7, 3
16, Communications, KeyAcc8, PerfMeas8, 3

Stored Procedure

declare @.var0 nchar(56)
declare @.var1 nchar(56)
declare keyaccscursor cursor for
(SELECT distinct category from
[CareerFramework].[dbo].[KeyAccountability] where jobprofileid = @.jobprofileID)
OPEN keyaccscursor
FETCH NEXT FROM keyaccscursor
INTO @.var1
WHILE @.@.FETCH_STATUS = 0
BEGIN
select distinct KeyAccountability as col1, 'keyacc' as rowtype from KeyAccountability where (category = @.var1) and (jobprofileid = @.jobprofileID)
union
select distinct category as col1, 'cat' as rowtype from KeyAccountability where (category = @.var1) and (jobprofileid = @.jobprofileID)
FETCH NEXT FROM keyaccscursor
INTO @.var1
END
CLOSE keyaccscursor
DEALLOCATE keyaccscursor

Results (when run in MSSQL Query Analyser )

-

KeyAccountability PerformanceMeasure (column headings)

Delivery

KeyAcc1 PerfMeas1

KeyAcc2 PerfMeas2

KeyAcc3 PerfMeas3

-

KeyAccountability PerformanceMeasure (column headings)

Department

KeyAcc4 PerfMeas3

KeyAcc5 PerfMeas4

KeyAcc6 PerfMeas5

-

KeyAccountability PerformanceMeasure (column headings)

Communications

KeyAcc7 PerfMeas6

KeyAcc7 PerfMeas7

I understand you have to present the following data

3, Delivery, KeyAcc2, PerfMeas2, 3
7, Delivery, KeyAcc3, PerfMeas3, 3
8, Department, KeyAcc4, PerfMeas4, 3
11, Department, KeyAcc5, PerfMeas5, 3
12, Department, KeyAcc6, PerfMeas6, 3
13, Communications, KeyAcc7, PerfMeas7, 3
16, Communications, KeyAcc8, PerfMeas8, 3

As

Delivery

KeyAcc2, PerfMeas2
KeyAcc3, PerfMeas3

And

Department

KeyAcc4, PerfMeas4, 3
KeyAcc5, PerfMeas5, 3

KeyAcc6, PerfMeas6, 3

And so on.

I should use a DropDownList cotrol with sqlsource ?SELECT distinct category from
[CareerFramework].[dbo].[KeyAccountability] where jobprofileid = @.jobprofileID”

And a GridView control with

Select KeyAccountability, PerformanceMeasure from KeyAccountability where Category=@.Categ

And @.categ is linked with DropDownList value.

Hope this help

|||

To fix your query for your requirement,

Code Snippet

declare @.var0 nchar(56)

declare @.var1 nchar(56)

declare @.jobprofileID as int

Set @.jobprofileID = 1

declare @.result table

(

col1 varchar(1000),

rowtype varchar(10)

)

declare keyaccscursor cursor for

(select distinct [category] from [keyaccountability] where jobprofileid = @.jobprofileid)

open keyaccscursor

fetch next from keyaccscursor

into @.var1

while @.@.fetch_status = 0

begin

Insert Into @.result

select keyaccountability as col1, 'keyacc' as rowtype from keyaccountability where (category = @.var1) and (jobprofileid = @.jobprofileid)

union

select category as col1, 'cat' as rowtype from keyaccountability where (category = @.var1) and (jobprofileid = @.jobprofileid)

fetch next from keyaccscursor

into @.var1

end

close keyaccscursor

deallocate keyaccscursor

Select * from @.result

|||

You can achieve the result without cursor also, (Highly recommended)

Code Snippet

declare @.jobprofileID as int

set @.jobprofileID = 1

select keyaccountability as col1, 'keyacc' as rowtype from keyaccountability where

(jobprofileid = @.jobprofileid)

union

select category as col1, 'cat' as rowtype from keyaccountability where

(jobprofileid = @.jobprofileid)

|||

Thanks very much for this - inserting into a table during the loop gives me the single data set - exactly as required.

There are 2 problems though, which may be related.

1.

The first is that I cannot declare a table in memory.

declare @.result table

(

col1 varchar(1000),

rowtype varchar(10)

)

gives me the following error:

Server: Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'table'.

(When I change to creating a permanent table using CREATE table, and run it in QA, the correct data populates the table.)

2.

When adding this into my stored procedure and running my webpage, the page breaks with the message that the recordset cannot be looped thru because it is closed.

When I comment out the insert statement but leave in the CREATE statement, the page works as it did before.

If you can help with this I would be very grateful.

Many thanks

Simon

|||

Hi,

I tried this also but although all the required results are returned as a single data set, KeyAccountabilities are not associated with the Categories as required.

All the Categories are listed in the top rows and then the KeyAccountabilities are listed in random order below. Looking at the SQL I can't see a way to group them as required using this method.

Would it be possible?

Many thanks

Simon

declare @.jobprofileID as int

set @.jobprofileID = 1

select keyaccountability as col1, 'keyacc' as rowtype from keyaccountability where

(jobprofileid = @.jobprofileid)

union

select category as col1, 'cat' as rowtype from keyaccountability where

(jobprofileid = @.jobprofileid)

|||

I am really wondering how its happen. What is the version of SQL Server you are using.

To find,

Select @.@.VERSION

Even on your ASP page you can change the RecordSet behaviour as UseClient istead of UseServer. It will fix the issue.

|||

The following query may fix your group/order issue,

Code Snippet

declare @.jobprofileID as int

set @.jobprofileID = 1

Select col1,rowtype from

(

select category,keyaccountability as col1, 'keyacc' as rowtype from keyaccountability where

(jobprofileid = @.jobprofileid)

Union

select category,category as col1, 'cat' as rowtype from keyaccountability where

(jobprofileid = @.jobprofileid)

) as Data

Order By

category, Case When rowtype='cat' Then 1 Else 2 End, Col1

|||Thank you

sql

Sunday, February 19, 2012

Help with TSQL where clause syntax

Hey everyone I want a where clause based off a variable input and I'm having some trouble with the syntax. My current code(incorrect) is below but it shows what I am aiming for. Does anyone have any suggestions?

Code Snippet

(CASE
WHEN @.inIndustry = 'ALL' THEN
WHERE EXISTS (SELECT 1 FROM sysdba.C_PROJECTREVENUE
WHERE OpportunityID = op.OpportunituID AND monthyear LIKE '%' + @.Year1)
ELSE
WHERE (acIF.Industry <> 'Defense' OR acIF.Industry IS NULL)
AND EXISTS (SELECT 1 FROM sysdba.C_PROJECTREVENUE
WHERE OpportunityID = op.OpportunituID AND monthyear LIKE '%' + @.Year1) END)


Maybe this:

Code Snippet

(CASE

WHEN @.inIndustry ='ALL'AND

EXISTS(SELECT 1 FROM sysdba.C_PROJECTREVENUE

WHERE OpportunityID = op.OpportunituID AND monthyear LIKE'%'+ @.Year1)

THEN 1

ELSE

CASEWHEN(acIF.Industry <>'Defense'OR acIF.Industry ISNULL)

ANDEXISTS(SELECT 1 FROM sysdba.C_PROJECTREVENUE

WHERE OpportunityID = op.OpportunituID AND monthyear LIKE'%'+ @.Year1)

THEN 1

ELSE 0

END--inner case

END)-- outer case

|||Hey. Thanks for the help but I dont see how that would work. I'm trying to make the WHERE clause dynamic in a way. It's all based off whatever the var @.inIndustry is equal to. So if @.inIndustry is equal to 'ALL' then is uses a certain where clause. I dont want to base the equivalence off of the entire statement there.|||

Code Snippet

WHERE(CASE

WHEN @.inIndustry ='ALL'AND

EXISTS(SELECT 1 FROM sysdba.C_PROJECTREVENUE

WHERE OpportunityID = op.OpportunituID AND monthyear LIKE'%'+ @.Year1)

THEN 1

WHEN(acIF.Industry <>'Defense'OR acIF.Industry ISNULL)

ANDEXISTS(SELECT 1 FROM sysdba.C_PROJECTREVENUE

WHERE OpportunityID = op.OpportunituID AND monthyear LIKE'%'+ @.Year1)

THEN 1

ELSE 0

END)

= 1

|||Ahh I see how it works now. I plugged it in and it works like a charm. Thanks for the help!
|||

No problem; my pleasure.

Much appreciated if you can mark the solution as the answer Smile

|||Actually it didnt work exactly as it should... This is the code i have at the moment.

Code Snippet


WHERE
(CASE
--MASTER
WHEN @.inIndustry = 'ALL'
AND EXISTS (SELECT 1 FROM sysdba.C_PROJECTREVENUE WHERE OpportunityID = op.OpportunityID AND monthyear LIKE '%' + @.Year1)

THEN 1

--ENERGY AND UTILITIES
WHEN @.inIndustry = 'EU' AND acIf.Industry = 'Energy and Utilities'
AND EXISTS (SELECT 1 FROM sysdba.C_PROJECTREVENUE WHERE OpportunityID = op.OpportunityID AND monthyear LIKE '%' + @.Year1)
THEN 1

-- NONGOV - E&U + OTHER
WHEN (acIF.Industry <> 'Defense' OR acIF.Industry IS NULL)
AND EXISTS (SELECT 1 FROM sysdba.C_PROJECTREVENUE WHERE OpportunityID = op.OpportunityID AND monthyear LIKE '%' + @.Year1)
THEN 1

ELSE 0
END) = 1

Now comparing original code and the code i wrote aboveI know that it performs the the last case statement no matter what i input for @.inIndustry. Is there any way to fix this?
|||

Nest CASE statements

CASE WHEN @.inIndustry = 'ALL' ..

ELSE

CASE WHEN ...

ELSE

END

END

|||I ended up adding checks to the last statement to make sure @.inIndustry wasn't equal to EU, ALL etc.. and it works fine now.

Thanks for all the help!