DECLARE
orderid NUMBER;
customerid NUMBER;
channel VARCHAR2(20);
amount NUMBER;
CURSOR orders_cursor IS
SELECT
order_id,
customer_id,
channel,
FINAL_PROFIT(order_id) AS amount
FROM temp_orders
FOR UPDATE ;
BEGIN
OPEN orders_cursor;
LOOP
FETCH orders_cursor INTO orderid, customerid, channel, amount;
EXIT WHEN orders_cursor%NOTFOUND;
IF amount < 0 THEN
INSERT INTO deficit (orderid, customerid, channel, amount)
VALUES (orderid, customerid, channel, -amount);
ELSE
INSERT INTO profit (orderid, customerid, channel, amount)
VALUES (orderid, customerid, channel, amount);
END IF;
END LOOP;
CLOSE orders_cursor;
END;
我有一个游标,它从函数 FINAL_PROFIT 中获取 order_id、customer_id、channel 和一个值,然后检查金额是正数还是负数并将其放入右侧表中。游标可以工作,但需要很长时间才能完成(30+分钟)。我需要它更快。 这是FINAL_PROFIT函数
create or replace FUNCTION FINAL_PROFIT (o_id NUMBER)
RETURN NUMBER
IS
f_profit FLOAT := 0;
v_delay NUMBER := 0;
BEGIN
v_delay := MAX_DELAY(o_id);
SELECT SUM(o.price - o.cost - (v_delay * (0.001 * TO_NUMBER(p.list_price,'9999.99')))) as FINAL_PROFT
INTO f_profit
FROM ORDERS o
JOIN PRODUCTS p ON o.product_id = p.product_id
WHERE o_id = o.order_id
GROUP BY o_id ;
RETURN f_profit;
END FINAL_PROFIT;
我尝试更新,因为我想让它更快,但我没有注意到时间上有任何差异
您很少会遇到需要在循环内运行 SQL 的情况,因此您几乎可以制定一条规则,如果您发现自己在想“我可以在循环中运行此 SQL”,那么您可以立即想到“所以我一定是想错了”。
相反,两个插入语句将处理这个问题:
INSERT INTO deficit (orderid, customerid, channel, amount)
SELECT
order_id,
customer_id,
channel,
FINAL_PROFIT(order_id) * -1 AS amount
FROM temp_orders
WHERE amount < 0;
INSERT INTO deficit (orderid, customerid, channel, amount)
SELECT
order_id,
customer_id,
channel,
FINAL_PROFIT(order_id) AS amount
FROM temp_orders
WHERE amount >= 0
该函数也可以更改为 SQL 的一部分,这样您就不会一次又一次地调用 sql 函数。