I’m getting started with my first use of a cursor in a stored procedure in sql server 2008. I’ve done some preliminary reading and I understand that they have significant performance limitations. In my current case I think they’re necessary (I want to run multiple stored procedures for each stock symbol in a symbols table.
Edit:
The sprocs I’ll be calling on each symbol will for the most part be insert operations to calculate symbol- dependent values, such as 5 day moving average, average daily volume, ATR (average true range). Most of these values will be calculated from data from a daily pricing and volume table… I’d like to streamline the retrieval of data values that would be retrieved redundantly otherwise… for example, I’d like to get for each symbol the daily pricing and volume data into a table variable… that temp table will then be passed in to the stored procedure that calls each of the aggregated functions I just mentioned. Hope that makes sense…
So my initial “outer loop” cursor- based stored procedure is below.. it times out after several minutes, without returning anything to the output window.
ALTER PROCEDURE dbo.sprocSymbolDependentAggsDriver2
AS
DECLARE @symbol nchar(10)
DECLARE symbolCursor CURSOR
STATIC FOR
SELECT Symbol FROM tblSymbolsMain ORDER BY Symbol
OPEN symbolCursor
FETCH NEXT FROM symbolCursor INTO @symbol
WHILE @@FETCH_STATUS = 0
SET @symbol = @symbol + ': Test.'
FETCH NEXT FROM symbolCursor INTO @symbol
CLOSE symbolCursor
DEALLOCATE symbolCursor
When I run it without the @symbol local variable and eliminate the assignment to it in the while loop, it seems to run ok. Is there a clear violation of performance best- practices within that assignment? Thanks..
You don’t really need all that explicit cursor jazz to build a string. Here is probably a more efficient way to do it:
Though I suspect you actually wanted to see the names of the symbol, e.g.
One caveat is that while you will typically observe the order to be observed, it is not guaranteed. So if you want to stick to the cursor, at least declare the cursor as follows:
Also it seems to me like NCHAR(10) is not sufficient to hold the data you’re trying to stuff into it, unless you only have one row (which is why I chose
NVARCHAR(MAX)above).And I agree with Abe… it is quite possible you don’t need to fire a stored procedure for every row in the cursor, but to suggest ways around that (which will almost certainly be more efficient), we’d have to understand what those stored procedures actually do.