我的以下代码未按预期运行。我收到以下错误:
Error at line 1
ORA-06550: line 20, column 18:
PLS-00201: identifier 'I' must be declared
ORA-06550: line 20, column 9:
PL/SQL: Statement ignored
我的代码:
DECLARE
process_limit CONSTANT SIMPLE_INTEGER := 500;
CURSOR c1 IS
SELECT * FROM cdtx cx
WHERE EXISTS (SELECT 1 FROM clmx c
WHERE c.cid = cx.cid);
TYPE t_c1 IS TABLE OF c1%ROWTYPE;
v_c1 t_c1;
BEGIN
OPEN c1;
LOOP
FETCH c1 BULK COLLECT INTO v_c1 LIMIT process_limit;
EXIT WHEN v_c1.COUNT = 0;
BEGIN
FORALL i IN 1..v_c1.COUNT
INSERT INTO cdx
(cid,
oind,
tind,
ot_date)
VALUES (v_c1(i).cid,
v_c1(i).new_oind,
v_c1(i).new_tind,
v_c1(i).ot_date);
COMMIT;
IF v_c1(i).new_t_amt IS NOT NULL
AND v_c1(i).new_t_date IS NOT NULL
THEN
INSERT INTO ctx
(cid,
t_amt,
t_date,
t_id)
VALUES
(v_c1(i).cid,
v_c1(i).new_t_amt,
v_c1(i).new_t_date,
'1');
COMMIT;
END IF;
END;
END LOOP;
END;
光标返回接近10k条记录。我最初有没有oracle的BULK COLLECT
功能的工作代码,但我认为BULK COLLECT
会更快。我在第20行尝试了IF
条件的几种变体而没有成功。我需要评估列new_t_amt
和new_t_date
并检查它们是否为NOT NULL
。只有在NOT NULL
INSERT
i = (char) System.in.read();
时才会发生import java.util.Scanner;
class WhileExample2{
public static void main(String args[]){
Scanner kb = new Scanner(System.in);
char i;
int a=100;
int b=20;
do
{
System.out.println("select your choice");
System.out.println("---------------------");
System.out.println("(1) Additon");
System.out.println("(2) Subtraction");
System.out.println("(3) Multiplication");
System.out.println("(4) Division");
i = kb.nextLine().charAt(0);
}while(i < '1' || i > '4');
//rest of code
}
}
。谢谢你的帮助。
答案 0 :(得分:1)
如果您使用光标进行循环,那么您可能会看到通过转移到批量收集来改进,请记住Thorsten在您的问题评论中提到的警告。
但是,您可以在单个insert语句中轻松执行此操作,假设您没有遇到任何限制(我希望没有从ctx.cid到cdx.cid的外键),像这样使用multitable insert:
INSERT ALL
WHEN new_t_amt IS NOT NULL
AND new_t_date IS NOT NULL THEN
INTO ctx (cid, t_amt, t_date, t_id) VALUES (cid, new_t_amt, new_t_date, '1')
WHEN 1 = 1 THEN INTO cdx (cid, oind, tind, ot_date) VALUES (cid, new_oind, new_tind, ot_date)
SELECT *
FROM cdtx cx
WHERE EXISTS (SELECT 1
FROM clmx c
WHERE c.cid = cx.cid);
答案 1 :(得分:1)
PL / SQL是一种直接安装在DBMS中的编程语言。但是,PL / SQL引擎仍必须与SQL引擎“对话”才能执行SQL语句。因此,直接运行SQL语句而不是调用PL / SQL函数总是更快。出于这个原因,Boneist建议使用mutli表插入,应该比你的方法更快。
在一些罕见的情况下,使用单个插入的经典方法可以证明更快。这特别适用于覆盖索引:
CREATE INDEX idx_for_cdx ON cdtx(cid, new_oind, new_tind, ot_date);
CREATE INDEX idx_for_ctx ON cdtx(cid, new_t_amt, new_t_date);
第二个索引中的列顺序可能很重要,因此您可以添加
CREATE INDEX idx_for_ctx2 ON cdtx(new_t_amt, new_t_date, cid);
并查看使用了哪个索引。
INSERT INTO cdx (cid, oind, tind, ot_date)
SELECT cid, new_oind, new_tind, ot_date
FROM cdtx
WHERE cid IN (SELECT cid FROM clmx);
INSERT INTO ctx (cid, t_amt, t_date, t_id)
SELECT cid, new_t_amt, new_t_date, '1'
FROM cdtx
WHERE cid IN (SELECT cid FROM clmx)
AND new_t_amt IS NOT NULL
AND new_t_date IS NOT NULL;
COMMIT;
如果您愿意,也可以将它放在匿名的PL / SQL块中:
BEGIN
INSERT INTO cdx ...
INSERT INTO ctx ...
COMMIT;
END;
唯一的区别是,从机器到数据库机器的往返次数会减少,因为这些将被移动到PL / SQL引擎和SQL引擎之间的数据库机器内。