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 2000 Forums
 SQL Server Development (2000)
 No Cursor.. need some help

Author  Topic 

slaurent
Starting Member

6 Posts

Posted - 2004-06-10 : 05:08:59
Hi All,

I have this query that I have built using a cursor. I know it is bad practice and horribly slow. I just can't find a way to do it without a cursor.
Can a guru give me some help?
Thanks
Stephanie

Here is the stored proc:
CREATE PROCEDURE [dbo].[usp_Index_ListStatements]

@AccountNumber as nvarchar(19),
@FromDate as datetime,
@ToDate as datetime
AS
SET NOCOUNT ON

DECLARE @TablePrefix as int


CREATE TABLE #TmpTable
(StatementDate datetime ,
AccountNumber nvarchar(19) COLLATE Latin1_General_CI_AS NOT NULL
)

DECLARE TableC CURSOR FOR
SELECT TablePrefix FROM Statements.dbo.directory WHERE rundate>=@FromDate AND rundate <=@ToDate
OPEN TableC
FETCH NEXT FROM TableC
INTO @TablePrefix
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO #TmpTable (StatementDate,AccountNumber)
EXEC ('SELECT StatementDate, AccountNumber FROM Statements.dbo.[' + @TablePrefix + '_headers] WHERE AccountNumber=' + @AccountNumber)


FETCH NEXT FROM TableC
INTO @TableIndex
END
CLOSE TableC
DEALLOCATE TableC
SELECT * FROM #TmpTable

sachinsamuel
Constraint Violating Yak Guru

383 Posts

Posted - 2004-06-10 : 05:52:29
Since the insert need to fired dynamicly, which are stored in the "Statements.dbo.directory" I don't think there is any other way which u r doing. But We can improve the way u r doing.

1) U can use table data types rather than temporary table.
2) U can use the sp_executeSQL rather than exec, which will help u to use the cache.

Let me know in case of any improvement.

Regards

Sachin
Go to Top of Page

RickD
Slow But Sure Yak Herding Master

3608 Posts

Posted - 2004-06-10 : 06:01:22
Simply just puting the original select into a #temp table will speed things up a bit...


CREATE PROCEDURE [dbo].[usp_Index_ListStatements]

@AccountNumber as nvarchar(19),
@FromDate as datetime,
@ToDate as datetime
AS
SET NOCOUNT ON

DECLARE @TablePrefix as int
DECLARE @TmpTable TABLE
(
StatementDate datetime ,
AccountNumber nvarchar(19) COLLATE Latin1_General_CI_AS NOT NULL
)
SELECT TablePrefix INTO #tmpPrefix FROM Statements.dbo.directory WHERE rundate>=@FromDate AND rundate <=@ToDate

DECLARE TableC CURSOR FOR
SELECT TablePrefix FROM #tmpPrefix
OPEN TableC
FETCH NEXT FROM TableC
INTO @TablePrefix
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO @TmpTable (StatementDate,AccountNumber)
EXEC ('SELECT StatementDate, AccountNumber FROM Statements.dbo.[' + @TablePrefix + '_headers] WHERE AccountNumber=' + @AccountNumber)

FETCH NEXT FROM TableC
INTO @TableIndex
END
CLOSE TableC
DEALLOCATE TableC
SELECT * FROM @TmpTable

Go to Top of Page

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-06-10 : 06:53:48
How many potential tables can TableC cursor return?
Have you considered UNION?
Go to Top of Page

slaurent
Starting Member

6 Posts

Posted - 2004-06-10 : 07:04:15
Sachin,

Thanks for your suggestions. It seems like I can't use the executeSQL as the prefix parameter is not a clause paramter but a table name parameter.

Also, if I use sp_executeSQL, I need to specify EXEC sp_executeSQL and it is not possible to fill up a table with the return of an exec. I get the following warning:
"execute cannot be used as a source when inserting into a table variable"

Thanks
Stephanie
quote:
Originally posted by sachinsamuel

Since the insert need to fired dynamicly, which are stored in the "Statements.dbo.directory" I don't think there is any other way which u r doing. But We can improve the way u r doing.

1) U can use table data types rather than temporary table.
2) U can use the sp_executeSQL rather than exec, which will help u to use the cache.

Let me know in case of any improvement.

Regards

Sachin

Go to Top of Page

RickD
Slow But Sure Yak Herding Master

3608 Posts

Posted - 2004-06-10 : 07:09:13
Whoops, forgot about that... Leave it as a pre-created #tmp table...
Go to Top of Page

slaurent
Starting Member

6 Posts

Posted - 2004-06-10 : 07:09:26
Hi,

there are 60 tables each containing 2.5 million records or more.
I have considered unions however i will not always want the records from all the tables. so i only want to "union" the required number to make it faster (union on 60 tables with that amount a record can be long..I'm assuming here...). the no of records returned by "SELECT TablePrefix FROM Statements.dbo.directory WHERE rundate>=@From AND rundate <=@To" tells me which tables out of the 60 to use.
thanks
stephanie
quote:
Originally posted by ehorn

How many potential tables can TableC cursor return?
Have you considered UNION?

Go to Top of Page

slaurent
Starting Member

6 Posts

Posted - 2004-06-10 : 07:11:57
no problem

quote:
Originally posted by RickD

Whoops, forgot about that... Leave it as a pre-created #tmp table...

Go to Top of Page
   

- Advertisement -