我使用触发器重新计算多个数据。 在触发器中我使用了cursor.in cursor我已经使用了另外一个包含1个光标的sp。
因此,仅计算80行数据的速度非常慢。计算数据需要20秒。所以请快速给我任何建议或解决方案。
感谢
这是我的触发器
/****** Object: Trigger [dbo].[tr_TransactionJournal_InsteadOfDelete] Script Date: 12/23/2015 3:13:09 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tr_TransactionJournal_InsteadOfDelete]
ON [dbo].[TransactionJournal]
INSTEAD OF DELETE
AS
SET NOCOUNT ON;
DECLARE
@TxNum INT,
@TxDate DATE
/*
declare @TempDetailTable to figure out which ChartAcctCode & Item needs to be recalculated
*/
DECLARE @TempDetailTable TABLE (
ChartAcctCode NVARCHAR(10),
ItemCode NVARCHAR(10)
)
DECLARE @MyCursor_1 CURSOR
SET @MyCursor_1 = CURSOR FAST_FORWARD
FOR
SELECT TxNum,TxDate FROM DELETED
OPEN @MyCursor_1
FETCH NEXT FROM @MyCursor_1
INTO @TxNum,@TxDate
WHILE @@fetch_status = 0 -- This is executed as long as the previous fetch succeeds.
BEGIN
------------------
BEGIN TRANSACTION
INSERT INTO @TempDetailTable
SELECT DISTINCT tjd.ChartAcctCode, tjd.ItemCode
FROM dbo.TransactionJournalDetail AS tjd
WHERE (tjd.TxNum = @TxNum)-- AND tjd.ItemCode IS NOT NULL
COMMIT TRANSACTION
/*
Actually deleting FROM TxJournal & TxJournalDetail
*/
DELETE FROM TransactionJournal WHERE TxNum=@TxNum
/*
Start Recalculating...
*/
DECLARE @MyChartAcctCode NVARCHAR(10)
DECLARE @MyItemCode NVARCHAR(10)
DECLARE @MyCursor CURSOR
/*
1st Loop to RecalcQAV if Detail has any ChartAcctCode = "AINV"
*/
SET @MyCursor = CURSOR FAST_FORWARD
FOR
SELECT ItemCode FROM @TempDetailTable WHERE ChartAcctCode = 'INV'
OPEN @MyCursor
FETCH NEXT FROM @MyCursor
INTO @MyItemCode
WHILE @@fetch_status = 0
BEGIN
EXEC RecalcQAV @MyItemCode, @TxDate;
FETCH NEXT FROM @MyCursor
INTO @MyItemCode
END
/*
2nd Loop to RecalcAcctBalance if Detail has any ChartAcctCode = "AINV"
*/
SET @MyCursor = CURSOR FAST_FORWARD
FOR
SELECT ChartAcctCode FROM @TempDetailTable
OPEN @MyCursor
FETCH NEXT FROM @MyCursor
INTO @MyChartAcctCode
WHILE @@fetch_status = 0
BEGIN
EXEC RecalcAcctBalance @MyChartAcctCode, @TxDate;
FETCH NEXT FROM @MyCursor
INTO @MyChartAcctCode
END
CLOSE @MyCursor;
DEALLOCATE @MyCursor;
------------------
FETCH NEXT FROM @MyCursor_1
INTO @TxNum,@TxDate
END
CLOSE @MyCursor_1;
DEALLOCATE @MyCursor_1;
答案 0 :(得分:0)
ALTER PROCEDURE [dbo].[RecalcAcctBalance]
(
@ChartAcctCode NVARCHAR(10),
@BeginDate DATE
)
AS BEGIN
SET NOCOUNT ON;
DECLARE @LastDate DATE
SELECT @LastDate = MAX(tj.TxDate)
FROM dbo.TransactionJournal AS tj
JOIN dbo.TransactionJournalDetail AS tjd ON tj.TxNum = tjd.TxNum
WHERE tj.TxDate < @BeginDate
AND tjd.ChartAcctCode = @ChartAcctCode
DECLARE @MyTable TABLE (
AutoId INT IDENTITY(1,1) PRIMARY KEY,
TxDate DATE,
TxDetailId INT
)
INSERT INTO @MyTable (TxDate, TxDetailId)
SELECT tj.TxDate, tjd.AutoId
FROM dbo.TransactionJournal AS tj
JOIN dbo.TransactionJournalDetail AS tjd ON tj.TxNum = tjd.TxNum
WHERE tj.TxDate >= ISNULL(@LastDate, @BeginDate)
AND tjd.ChartAcctCode = @ChartAcctCode
ORDER BY tj.TxDate, tj.SourceDocOrder, tjd.AutoId
DECLARE
@LastDateMaxId INT,
@TxDetailId INT,
@LChartAcctBalance MONEY = 0
IF @LastDate IS NOT NULL
BEGIN
SELECT @TxDetailId = TxDetailId
FROM (
SELECT TxDetailId, RowNum = ROW_NUMBER() OVER (ORDER BY AutoId DESC)
FROM @MyTable
WHERE TxDate = @LastDate
) t
WHERE t.RowNum = 1
SELECT @LChartAcctBalance = ISNULL(ChartAcctBalance, 0)
FROM dbo.TransactionJournalDetail
WHERE AutoId = @TxDetailId
END
;WITH cte AS
(
SELECT *, val = @LChartAcctBalance + SUM(Amount) OVER (ORDER BY AutoId)
FROM dbo.TransactionJournalDetail
WHERE AutoId IN (
SELECT TxDetailId
FROM @MyTable
WHERE TxDate >= @BeginDate
)
)
UPDATE cte
SET ChartAcctBalance = val
END
第二个sp太大了,无法进行重构......无论如何主要问题 - 按项目处理的业务逻辑......