下面的脚本需要10 多个小时才能执行.. 它包含three nested cursors
并且我认为它们是罪魁祸首。我搜索了很多以替换光标或提高脚本的性能。并找到了很多方法来删除cursor
. 例如简单的集合连接操作、Marge 操作等。但我仍然无法在我的脚本中实现它们。请看一下剧本并给出一些意见
- 在不影响输出的情况下,是否可以删除内部光标
- 如果可能的话怎么办?如果可能,请提供一些代码
DECLARE @Start_Date Date = '1990-01-01'
DECLARE @End_Date Date = '2012-12-12'
DECLARE @Company_ID int = 180
declare @BP_ID [int]
DECLARE All_Client_Bp_Id CURSOR STATIC FOR
SELECT TOP 50 Bp_id FROM Client --Take All Client's BPID
OPEN All_Client_Bp_Id
FETCH NEXT FROM All_Client_Bp_Id
INTO @BP_ID
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @acrdint MONEY
DECLARE @acrdSrv MONEY
DECLARE @MaxMargLimit MONEY
DECLARE @ForceLimit MONEY
DECLARE @WarningLimit MONEY
DECLARE @MarginLimit DECIMAL(5,2)
select @MaxMargLimit=Highest_Margin_Limit*100000,@ForceLimit=Force_Sell_Limit,@WarningLimit=Margin_Warning_Limit, @MarginLimit = Margin_Limit
from Client_Margin_Constraints c
inner join (select Bp_id, max(Update_Date) as updt
from Client_Margin_Constraints
where Update_Date <= @End_Date and Bp_id = @BP_ID and Company_ID = @Company_ID
group by Bp_id) b
on c.Bp_id = b.Bp_id and c.Update_Date = b.updt
DELETE FROM Temp_Portfolio
INSERT INTO Temp_Portfolio (Client_BP_ID, tran_date, Instrument_ID, Is_Buy, Quantity, Amount, Commission, Rate, Category,Tax_Amount)
SELECT t.Client_BP_ID, t.tran_date, t.Instrument_ID, t.Is_Buy, t.Quantity, t.Amount, t.Commission,
t.Rate, t.Category, t.Tax_Amount
FROM All_Share_Txn t
WHERE t.Client_BP_ID = @BP_ID
DECLARE @Instrument_Id int,
@bqty int,
@bamt MONEY,
@brate MONEY,
@srate MONEY,
@rprofit MONEY,
@mslbqty int,
@BCost MONEY,
@SCost MONEY,
@BCqty int,
@SCqty int,
@B_Or_S CHAR(1),
@CDBL_Type CHAR(1),
@Qty INT,
@MktPrice MONEY,
@Amount MONEY,
@Commission MONEY,
@TDATE SMALLDATETIME,
@DES CHAR(30),
@TotalProfit MONEY,
@Category CHAR(1)
SET @TotalProfit = 0
DECLARE CUR_SHARE CURSOR STATIC FOR
SELECT DISTINCT Instrument_Id
FROM Temp_Portfolio
OPEN CUR_SHARE
FETCH NEXT FROM CUR_SHARE
INTO @Instrument_Id
WHILE @@FETCH_STATUS = 0
BEGIN
SET @bqty = 0
SET @bamt = 0
SET @brate = 0
SET @srate = 0
SET @rprofit = 0
SET @mslbqty = 0
SET @BCost = 0
SET @SCost = 0
SET @BCqty = 0
SET @SCqty = 0
DECLARE CUR_COST CURSOR STATIC FOR
SELECT Is_buy,Quantity,rate,Amount,Commission,Tran_date
FROM Temp_Portfolio
WHERE Client_Bp_id=@BP_ID and Instrument_Id=@Instrument_Id
ORDER BY Tran_date,Is_buy desc,Category
OPEN CUR_COST
FETCH NEXT FROM CUR_COST
INTO @B_Or_S,@Qty,@MktPrice,@Amount,@Commission,@TDATE
WHILE @@FETCH_STATUS = 0
BEGIN
IF @B_Or_S='1'
BEGIN
SET @bqty = @bqty + @Qty
SET @bamt = @bamt + @Amount + @Commission
IF @bqty > 0
SET @brate = @bamt/@bqty
END
ELSE IF @B_Or_S='0'
BEGIN
SET @srate = @MktPrice
IF @TDATE > @Start_Date and @TDATE <= @End_Date
BEGIN
SET @rprofit = @rprofit + ((@srate - @brate) * @Qty) - @Commission
SET @BCqty = @BCqty + @Qty
SET @SCqty = @SCqty + @Qty
SET @BCost = @BCost + (@Brate * @Qty)
SET @SCost = @SCost + (@Srate * @Qty) - @Commission
END
SET @bamt = @bamt - (@brate * @Qty)
SET @bqty = @bqty - @Qty
END
FETCH NEXT FROM CUR_COST
INTO @B_Or_S,@Qty,@MktPrice,@Amount,@Commission,@TDATE
END
SET @TotalProfit=@TotalProfit+@rprofit
CLOSE CUR_COST
DEALLOCATE CUR_COST
FETCH NEXT FROM CUR_SHARE
INTO @Instrument_Id
END
CLOSE CUR_SHARE
DEALLOCATE CUR_SHARE
--Select @TotalProfit as Realised_Gain
-- Equity, Purchase Power Calculation
DECLARE @Equity_All MONEY
DECLARE @Equity_Margin MONEY
DECLARE @Current_Balance MONEY
DECLARE @temp_Purchase_Power_1 MONEY
DECLARE @temp_Purchase_Power_2 MONEY
DECLARE @Purchase_Power MONEY
--Balance
select @Current_Balance = sum((case when a.Is_Share_TXN='1' and a.Is_Debit='1' then -a.amount when a.Is_Share_TXN='1' and a.Is_Debit='0' then a.amount when a.Is_Share_TXN='0' and a.Is_Debit='0' then a.amount when a.Is_Share_TXN='0' and a.Is_Debit='1' then -a.amount end) -a.Commission)
from Client_Transaction a where a.Client_Bp_id = @BP_ID and a.Transaction_Date < @End_Date and a.Company_Id=@Company_Id
group by a.Client_Bp_id--dbo.get_Current_Balance(@BP_ID, @End_Date, @Company_ID)
--Equity Margin
SELECT @Equity_Margin = SUM(CASE WHEN t_Margin.Is_Marginable_Securities = 'True' Then t_Margin.Total_Quantity * t_Margin.Market_price END),
@Equity_All = SUM(t_Margin.Total_Quantity * t_Margin.Market_price)
FROM
(
select t2.Is_Marginable_Securities, --t3.Bp_Code as Client_Code,t3.Bp_Name as Client_Name,t4.Bo_Id_DSE,t1.Instrument_ID,
sum(case when Is_buy='True' then Quantity when Is_buy='False' then -quantity end) as Total_Quantity,
--sum(case when ISNULL(t1.Mature_Date_Share,t1.tran_date) <= @Transaction_Date then (case Is_buy when '1' then quantity when '0' then -quantity end) else 0 end) as Free_Quantity,
INDX.Closing_Price AS Market_price
from dbo.View_All_Share_Transactions_with_PledgeUnpledge t1 left outer join Instrument t2 on t1.Instrument_Id=t2.Instrument_ID
left outer join (
select Closing_Price from Index_Price ip
where ip.Txn_Date=(select MAX(Txn_Date) from Index_Price ip2 where ip2.Instrument_Id=ip.Instrument_Id)
) INDX
ON t1.Instrument_ID = INDX.Closing_Price
where Client_Bp_id = @BP_ID and t1.Instrument_ID is not null and tran_date <=@End_Date and t1.Is_Pledge_Unpledge = 'False'
group by t1.Instrument_ID,t2.Is_Marginable_Securities, INDX.Closing_Price
having sum(case when Is_buy='True' then Quantity when Is_buy='False' then -quantity end)<> 0
) t_Margin --dbo.get_Equity_Margin(@BP_ID, @End_Date, @Company_ID)
SET @Equity_Margin = @Equity_Margin + @Current_Balance
SET @Equity_All = @Equity_All + @Current_Balance
SET @temp_Purchase_Power_1 = (@Equity_Margin * (@MarginLimit / 100)) + @Current_Balance
SET @temp_Purchase_Power_2 = ISNULL(@MaxMargLimit,0) + ISNULL(@Current_Balance,0)
IF (@temp_Purchase_Power_1 < @temp_Purchase_Power_2)
BEGIN
SET @Purchase_Power = @temp_Purchase_Power_1
END
ELSE
BEGIN
SET @Purchase_Power = @temp_Purchase_Power_2
END
INSERT Client_Account_Balance (
BP_ID,
Equity_All,
Equity_Margin,
Purchase_Power,
Margin_Ratio,
Total_Deposit,
Withdraw,
Charges,
Current_Balance,
Aaccured_Charges,
Max_Margin_LImit,
Margin_Limit,
Realised_Gain,
Company_ID,
Created_By,
Updated_By
)
SELECT @BP_ID, @Equity_All,@Equity_Margin ,@Purchase_Power ,
CASE WHEN (@Current_Balance - ISNULL(@acrdSrv,0)) != 0 THEN (@Equity_Margin - @Current_Balance) * (-100)/(@Current_Balance - ISNULL(@acrdSrv,0)) ELSE 0 END,
TDEP,TWDRAW,TCHARGES,BALANCE,ACC_CHARGE,@MaxMargLimit ,@MarginLimit,
@TotalProfit,
180,1,1
FROM
(SELECT SUM(DEPOSITE) AS TDEP,SUM(WDRAW) AS TWDRAW,SUM(CHARGES) AS TCHARGES,SUM(DEBCRED-Commission) AS BALANCE,SUM(ISNULL(@acrdint,0)+ISNULL(@acrdSrv,0)) AS ACC_CHARGE
FROM
(SELECT (CASE
WHEN tran_date >= @Start_Date THEN
CASE Is_Share_TXN
WHEN '0' THEN
CASE Is_Debit
WHEN '1' THEN 0
ELSE AMOUNT END
ELSE 0 END
ELSE 0 END) AS Deposite,
(CASE
WHEN tran_date >= @Start_Date THEN
CASE Is_Share_TXN
WHEN '0' THEN
CASE Is_Debit
WHEN '1' THEN
CASE T_TYPE
WHEN '1' THEN AMOUNT
WHEN '3' THEN AMOUNT
WHEN 'T' THEN AMOUNT
ELSE 0 END
ELSE 0 END
ELSE 0 END
ELSE 0 END) AS WDRAW,
(CASE
WHEN tran_date >= @Start_Date THEN
CASE Is_Share_TXN
WHEN '0' THEN
CASE Is_Debit
WHEN '1' THEN
CASE T_TYPE
WHEN '1' THEN 0
WHEN '3' THEN 0
WHEN 'T' THEN 0
ELSE AMOUNT END
ELSE 0 END
ELSE 0 END
ELSE 0 END) AS CHARGES,
(CASE Is_Share_TXN
WHEN '1' THEN
CASE Is_Debit
WHEN '1' THEN -AMOUNT
ELSE AMOUNT END
When '0' THEN
CASE Is_Debit
WHEN '1' THEN -AMOUNT
ELSE AMOUNT END
END) AS DEBCRED,Commission
FROM View_All_Transaction
WHERE tran_date <= @End_Date
AND Client_Bp_id = @BP_ID ) AS A) AS B
FETCH NEXT FROM All_Client_Bp_Id
INTO @BP_ID
END
CLOSE All_Client_Bp_Id
DEALLOCATE All_Client_Bp_Id