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.
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?ThanksStephanieHere is the stored proc:CREATE PROCEDURE [dbo].[usp_Index_ListStatements] @AccountNumber as nvarchar(19), @FromDate as datetime, @ToDate as datetimeAS 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.RegardsSachin |
|
|
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 datetimeASSET NOCOUNT ONDECLARE @TablePrefix as intDECLARE @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 <=@ToDateDECLARE TableC CURSOR FORSELECT TablePrefix FROM #tmpPrefixOPEN TableCFETCH NEXT FROM TableCINTO @TablePrefixWHILE @@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 ENDCLOSE TableCDEALLOCATE TableCSELECT * FROM @TmpTable |
|
|
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? |
|
|
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"ThanksStephaniequote: 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.RegardsSachin
|
|
|
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... |
|
|
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.thanksstephaniequote: Originally posted by ehorn How many potential tables can TableC cursor return?Have you considered UNION?
|
|
|
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...
|
|
|
|
|
|
|
|