December 18, 2003 at 1:32 pm
I am trying to write a stored procedure that has nested cursors.
The table name of the second level cursor changes with every fetch stmt of the first cursor. Hence it has a variable name for its table name in its SELECT stmt. But I keep getting an error
Here is the sample code
OPEN cursor1
FETCH cursor1 into @countyt
while @@FETCH_STATUS = 0
BEGIN
DECLARE cursor3 CURSOR FOR
SELECT County,Qualifier,Lseries from LandRecords..tblLandRec_Index_Series where County=@countyt
FOR READ ONLY
-- SELECT @countyt
OPEN cursor3
FETCH cursor3 into @county, @Qualifier, @series
while @@FETCH_STATUS = 0
BEGIN
SET @filename = 'tblFilenames_' + @Qualifier + @series
print @filename
set @filename = 'Volume_Control' + '.dbo.' + @filename
print @filename
DECLARE cursor2 CURSOR
GLOBAL
DYNAMIC
FOR
SELECT sum(file_size_bytes) , Lseries from @filename group by Lseries
FOR READ ONLY
I get an error :
Must declare the variable @filename for the last SELECT
Any help would be appreciated.
-Thri
December 18, 2003 at 2:56 pm
Try creating a temp table right before you declare your last cursor. Have your cursor select from the temp table.
December 18, 2003 at 5:07 pm
jxflagg is correct. If you create a temp table and then use dynamic sql to fill it you should be able to create a cursor against it with no problems. BUT, is there anyway you can solve this issue without nesting cursors 3 levels deep? This sounds like a really performance degrading routine to me.
Gary Johnson
Microsoft Natural Language Group
DBA, Sr. DB Engineer
Gary Johnson
Microsoft Natural Language Group
DBA, Sr. DB Engineer
This posting is provided "AS IS" with no warranties, and confers no rights. The opinions expressed in this post are my own and may not reflect that of my employer.
December 19, 2003 at 6:33 am
Change the cursor2 declare to this
declare @sql nvarchar(4000)
set @sql = '
DECLARE cursor2 CURSOR
GLOBAL
DYNAMIC
FOR
SELECT sum(file_size_bytes) , Lseries from ' + @filename + ' group by Lseries
FOR READ ONLY
'
exec(@sql)
Far away is close at hand in the images of elsewhere.
Anon.
December 19, 2003 at 7:51 am
Thanks for your suggestions. This is a wonderful group with everybody giving such prompt responses.
Thanks David, the exec enclosing the cursor works.
But I have been toying with the idea of creating a temp table as jxflagg and Gary have suggested. Would a temp table be better as far as performance goes ? Is there anyway I can these cursors into joins so that I can avoid the cursors ? I am a novice at creating joins.
Thanks again.
December 19, 2003 at 8:08 am
The problem is that your table names are in a table and that is why you are using cursors.
How many 'Volume_Control.tblFilenames_' tables are there and what size are they (rows). Is the number fixed or variable.
If you want all the results in one recordset then the use of a temp table would be required.
A join would be difficult as per above. The only way I can see to use a join would be to union all the tblFilenames_ together and join that result with LandRecords..tblLandRec_Index_Series.
Far away is close at hand in the images of elsewhere.
Anon.
December 19, 2003 at 11:05 am
The number of tables are about 150 now and the number of rows anywhere from 0 to a million in each table. The number of tables and rows can increase in future as they get updated once a week/2 weeks. The table name has to be obtained dynamically since the it put together as tblFilenames_XY based on X and Y fields that I can get that from tblLandRec_Index_Series and another table taht has similar info. From each table tblFilenames_XY, I need only 1-5 rows of data required for calculating statistics that I would put into a temp table . These would be eventually displayed using ACCESS (hopefully !). Would these nested cursors degrade the performance severely ?
December 19, 2003 at 11:24 am
I think the real problem is that the schema violates Codd's Information Rule by having identifiers (i.e. table names) connote information. That's why you now need cursors, dynamic SQL, temporary tables, UNIONs and other kludges. Do not create multiple tables with exactly the same columns but differing names; instead create one table with an additional column to hold the information you added to the table names. SQL Server works very well with large tables.
--Jonathan
--Jonathan
December 19, 2003 at 11:24 am
What would be your max number of tables per @countyt?
I'm thinking something in the line of
(David's modified)
declare @sql nvarchar(4000)
set @sql = 'DECLARE cursor2
CURSOR GLOBALDYNAMIC FOR
SELECT Convert(Int, 0) as SumOf_file_size_bytes , Convert(Char(x), NULL) as Lseries WHERE 1=2 -- Dummy to establish structure' + Char(13) + Char(10)
Select @sql = @sql +
'UNION ALL SELECT sum(file_size_bytes) , Lseries
from Volume_Control.dbo.tblFilenames_' + Qualifier + Lseries + '
group by Lseries FOR READ ONLY' + Char(13) + Char(10)
From LandRecords..tblLandRec_Index_Series where County=@countyt
exec(@sql)
Once you understand the BITs, all the pieces come together
December 19, 2003 at 3:02 pm
Thomas, Per @countyt I could have 100 to 150 rows. I will try out the sql stmt that you have mentione and get back on how it worked.
Jonathan, This database was designed well before i got here and there is too much data now , so we cannot change the design but it is agreed here that there should nto have been 2 tables with the same stucture. So i have to just work with it.
December 22, 2003 at 12:31 pm
Thanku very much friends. The sproc works well now.
Viewing 11 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply