Преобразовать курсор в опережение / отставание - MySQL - PullRequest
0 голосов
/ 01 мая 2020

У меня есть следующая хранимая процедура:

DELIMITER //

CREATE PROCEDURE runAmortization(
    IN p_accountNumber varchar(50),
    IN p_apr decimal(17,15),
    IN p_principalBalanceOfLoan decimal(10,2),
    IN p_amountFinancedOfLoan decimal(10,2),
    IN p_financeCharge decimal(10,2),
    IN p_contractDateOfLoan datetime
)

BEGIN

    DECLARE v_bCursorFinished INT DEFAULT 0;
    DECLARE v_interestRemaining DECIMAL(8,2)  DEFAULT 0;
    DECLARE v_effectiveDate datetime;
    DECLARE v_previousEffectiveDate datetime;
    DECLARE v_principal DECIMAL(18,2)  DEFAULT 0;
    DECLARE v_type varchar(50);
    DECLARE v_principalRemaining DECIMAL(10,2)  DEFAULT 0;
    DECLARE v_daysBetween int  DEFAULT 0;
    DECLARE v_varianceAmount DECIMAL(10,2)  DEFAULT 0;
    DECLARE v_inVariance BIT;


    DECLARE transactionsCursor 
        CURSOR FOR 
                SELECT 
                    TranEffectiveDate, 
                    Amount, 
                    Upper(Type) as PaymentType 
                FROM 
                    transactions 
                WHERE 
                    AccountNumber = p_accountNumber
                ORDER BY 
                    TranEffectiveDate ASC;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_bCursorFinished = 1;

    SET v_principalRemaining = p_amountFinancedOfLoan + COALESCE(p_financeCharge, 0);
    SET v_previousEffectiveDate = p_contractDateOfLoan;

    DROP TABLE IF EXISTS tblAmortizationResults;
    CREATE TEMPORARY TABLE IF NOT EXISTS tblAmortizationResults 
    (
             payment_date DateTime,
             payment decimal(10,2),
             type varchar(30),
             principal_remaining decimal(18,2),
             days_between_payment int NULL
    );

      OPEN transactionsCursor;
      FETCH transactionsCursor INTO v_effectiveDate, v_principal, v_type;

      INSERT INTO tblAmortizationResults 
      (payment, payment_date,  type, principal_remaining)
      VALUES 
      (0, p_contractDateOfLoan, 'PAYMENT', v_principalRemaining); 

     runAmort: LOOP

        FETCH transactionsCursor INTO v_effectiveDate, v_principal, v_type;

        IF v_bCursorFinished = 1 THEN
            LEAVE runAmort;
        END IF;

        SET v_daysBetween = DATEDIFF(v_previousEffectiveDate, v_effectiveDate);
        SET v_principalRemaining = v_principalRemaining - v_principal;

        INSERT INTO tblAmortizationResults 
        (payment_date, payment, type, principal_remaining, days_between_payment)
        VALUES 
        (v_effectiveDate, v_principal, v_type, v_principalRemaining, v_daysBetween); 

        SET v_previousEffectiveDate = v_effectiveDate;

     END LOOP runAmort;
     CLOSE transactionsCursor;

     INSERT INTO amortization
     (account_number, payment_date, payment, type, principal_remaining, days_between_payment, created_date)
     SELECT
     p_accountNumber, payment_date, payment, type, principal_remaining, days_between_payment, CURRENT_TIMESTAMP
     FROM tblAmortizationResults;

     SET v_varianceAmount = (p_principalBalanceOfLoan - v_principalRemaining);
     SET v_inVariance = 0;


     IF v_varianceAmount >= -50 AND v_varianceAmount <= 50 THEN
        SET v_inVariance = 1;
     END IF;

     INSERT INTO amortization_variance
     (account_number, variance, last_calculated, in_variance)
      VALUES
      (p_accountNumber, v_varianceAmount, CURRENT_TIMESTAMP, v_inVariance);

END //

DELIMITER ;

Как вы можете видеть, я беру данные из таблицы transactions, а затем перемещаю курсор по ней, чтобы обработать каждую строку данных. Я использую переменные между каждой итерацией для хранения значений, которые в конечном итоге вставляются в таблицу базы данных.

Я чувствую, что есть способ использовать LEAD() и LAG() вместо этого, но не могу понять как ... кто-нибудь может "привести" меня в правильном направлении?

Спасибо за любой вклад

...