Sta*_*Csh 4 sql-server sql-server-2008-r2
我开始在sql server 2008中第一次使用存储过程中的游标.我已经做了一些初步阅读,我知道它们有很大的性能限制.在我目前的情况下,我认为它们是必要的(我想在符号表中为每个股票代码运行多个存储过程.
编辑:我将在每个符号上调用的sprocs大部分是插入操作来计算符号相关值,例如5天移动平均值,平均每日交易量,ATR(平均真实范围).这些值中的大部分将根据每日定价和数量表中的数据进行计算...我想简化对冗余检索的数据值的检索,否则...例如,我想得到每个值将每日定价和卷数据符号转换为表变量...然后将临时表传递给调用我刚刚提到的每个聚合函数的存储过程.希望有道理......
所以我的初始"外循环"基于光标的存储过程在下面..它在几分钟后超时,而没有返回到输出窗口.
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
Run Code Online (Sandbox Code Playgroud)
当我在没有@symbol局部变量的情况下运行它并在while循环中消除它的赋值时,它似乎运行正常.在该任务中是否明显违反了绩效最佳做法?谢谢..
"在我目前的情况下,我认为它们是必要的(我想在符号表中为每个股票代码运行多个存储过程."
游标很少是必需的.
从上面的例子中,我认为一个简单的WHILE循环很容易取代你的光标.改编自SQL游标 - 如何避免它们(我最喜欢的SQL书签之一)
-- Create a temporary table...
CREATE TABLE #Symbols (
RowID int IDENTITY(1, 1),
Symbol(nvarchar(max))
)
DECLARE @NumberRecords int, @RowCount int
DECLARE @Symbol nvarchar(max)
-- Get your data that you want to loop over
INSERT INTO #Symbols (Symbol)
SELECT Symbol
FROM tblSymbolsMain
ORDER BY Symbol
-- Get the number of records you just grabbed
SET @NumberRecords = @@ROWCOUNT
SET @RowCount = 1
-- Just do a WHILE loop. No cursor necessary.
WHILE @RowCount <= @NumberRecords
BEGIN
SELECT @Symbol = Symbol
FROM #Symbols
WHERE RowID = @RowCount
EXEC <myProc1> @Symbol
EXEC <myProc2> @Symbol
EXEC <myProc3> @Symbol
SET @RowCount = @RowCount + 1
END
DROP TABLE #Symbols
Run Code Online (Sandbox Code Playgroud)
您实际上并不需要所有显式的光标爵士乐来构建字符串。这可能是一种更有效的方法:
DECLARE @symbol NVARCHAR(MAX) = N'';
SELECT @symbol += ': Test.'
FROM dbo.tblSymbolsMain
ORDER BY Symbol;
Run Code Online (Sandbox Code Playgroud)
尽管我怀疑您实际上想查看符号的名称,例如
DECLARE @symbol NVARCHAR(MAX) = N'';
SELECT @symbol += N':' + Symbol
FROM dbo.tblSymbolsMain
ORDER BY Symbol;
Run Code Online (Sandbox Code Playgroud)
需要注意的是,虽然您通常会遵守要遵守的顺序,但这并不能保证。所以如果你想坚持光标,至少要按如下方式声明光标:
DECLARE symbolCursor CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
...
Run Code Online (Sandbox Code Playgroud)
另外,在我看来, NCHAR(10) 不足以保存您尝试填充到其中的数据,除非您只有一行(这就是我在NVARCHAR(MAX)上面选择的原因)。
我同意 Abe 的观点......您很可能不需要为游标中的每一行触发存储过程,但要提出解决方法(这几乎肯定会更有效),我们必须了解这些存储过程的实际用途。
| 归档时间: |
|
| 查看次数: |
15195 次 |
| 最近记录: |