我必须在X,Y,Z之间选择一个数字。
选择号码前的验证如下:
如果有多个数字满足上述验证,则选择最接近B的数字。
注意:我使用的是Oracle 10g版本。
这是我写的代码。虽然我没有找到理想的代码。 因此寻找更好的解决方案。
PROCEDURE calc_amt (p_txn_no IN NUMBER,
X IN NUMBER,
Y IN NUMBER,
Z IN NUMBER,
A IN NUMBER,
B IN NUMBER,
p_calc_amnt OUT NUMBER,
p_error OUT VARCHAR2)
IS
v_fin_cnt NUMBER;
v_calc_amnt NUMBER;
TYPE p_temp_array IS TABLE OF NUMBER
INDEX BY PLS_INTEGER;
p_temp p_temp_array;
BEGIN
p_temp (1) := X;
p_temp (2) := Y;
p_temp (3) := Z;
DELETE xxcrm_val_temp
WHERE txn_no = p_txn_no;
COMMIT;
--Perform Validations
FOR i IN 1 .. p_temp.COUNT
LOOP
BEGIN
INSERT INTO xxcrm_val_temp
VALUES (p_txn_no,
i,
p_temp (i),
'S');
COMMIT;
IF (p_temp (i) NOT BETWEEN (Z / 1.5) AND A) --Number should be greater then Z/1.5 and less than A
OR (p_temp (i) < X AND p_temp (i) < Y) --Number should not be lest than X and Y both
THEN
--Remove error numbers
UPDATE xxcrm_val_temp
SET err_flag = 'E'
WHERE txn_no = p_txn_no AND seq = i;
COMMIT;
--Delete number that do not satisfy the validations
p_temp.delete (i);
END IF;
EXCEPTION
WHEN OTHERS
THEN
NULL;
END;
END LOOP;
v_fin_cnt := p_temp.COUNT;
--Find the closest number to the number B
IF v_fin_cnt = 0
THEN
p_error := 'E';
p_calc_amnt := 0;
ELSIF v_fin_cnt > 0
THEN
--Query to find closest number to B
WITH diff
AS (SELECT t.temp_amt, ABS (B - t.temp_amt) diff
FROM xxcrm_val_temp t
WHERE txn_no = p_txn_no AND err_flag = 'S')
SELECT d.temp_amt
INTO p_calc_amnt
FROM diff d
WHERE d.diff = (SELECT MIN (d1.diff)
FROM diff d1)
AND ROWNUM = 1;
p_error := 'S';
END IF;
EXCEPTION
WHEN OTHERS
THEN
NULL;
END calc_amt;