嗨朋友我有一个perl脚本,它通过sqlplus与oracle Db交互。我在这里运行两个查询。第一个查询从视图中提取特定日期的序列号并写入文件。
SELECT DISTINCT serialnumber FROM VOUCHERHISTORYCLIENTV WHERE at LIKE '&1'; (where &1 = $date)
然后perl循环读取此文件,逐行获取序列号&运行以下查询,将数据写入另一个文件,然后由以下perl代码处理。现在这些序列号太大了,所以循环连接到sqlplus的每次迭代运行查询&生成输出&然后断开连接。这就是为什么它花了太多时间。
SELECT * FROM VSOWNERUPE07.VOUCHERHISTORYCLIENTV WHERE serialnumber = '&1'; (where &1 = $serialnumber)
有什么方法我不需要连接&再次断开sqlplus会话&再次?我最终想要的是对unix文件中附加的每个迭代的第二个查询的结果。所以我的perl脚本可以格式化它们。我猜pl / sql循环可以做到这一点......但我从来没有在pl / sql上工作过...你能帮我吗?
PS:我不能在这里使用DBD :: oracle,因为我在solaris mahine& amp; amp;因为这个服务器是第三方服务器所以我不能在这个
上做任何chnages更新:1
我试过以下两个程序&运行特定日期,表有600万条记录。但查询一直在运行&即使在2天后也没有产生任何产量...
程序#1:
DECLARE
CURSOR CUR1 IS
SELECT DISTINCT serialnumber FROM VSOWNERUPE07.VOUCHERHISTORYCLIENTV WHERE at LIKE '&1';
CURSOR CUR2(p_ser_num NUMBER) IS
SELECT serialnumber, state, at as time1, operatorid FROM VSOWNERUPE07.VOUCHERHISTORYCLIENTV WHERE serialnumber = p_ser_num;
BEGIN
FOR l_cur1 IN CUR1
LOOP
NULL;
FOR l_cur2 IN CUR2(l_cur1.serialnumber)
LOOP
DBMS_OUTPUT.PUT_LINE(l_cur2.serialnumber||' '||l_cur2.state ||' '||l_cur2.time1 ||' '||l_cur2.operatorid );
END LOOP;
END LOOP;
END;
/
quit;
程序#2:
DECLARE
CURSOR CUR1 IS
SELECT DISTINCT serialnumber FROM VSOWNERUPE07.VOUCHERHISTORYCLIENTV WHERE at LIKE '&1';
TYPE t_tab1 IS TABLE OF CUR1%ROWTYPE;
l_tab1 t_tab1;
CURSOR CUR2(p_ser_num NUMBER) IS
SELECT serialnumber, state, at as time1, operatorid FROM VSOWNERUPE07.VOUCHERHISTORYCLIENTV WHERE serialnumber = p_ser_num;
TYPE t_tab2 IS TABLE OF CUR2%ROWTYPE;
l_tab2 t_tab2;
BEGIN
OPEN CUR1;
LOOP
FETCH CUR1 BULK COLLECT INTO l_tab1;
EXIT WHEN CUR1%NOTFOUND;
END LOOP;
CLOSE CUR1;
FOR i in 1..l_tab1.COUNT
LOOP
OPEN CUR2(l_tab1(i).serialnumber);
LOOP
FETCH CUR2 BULK COLLECT INTO l_tab2;
EXIT WHEN CUR2%NOTFOUND;
END LOOP;
CLOSE CUR2;
for j in 1..l_tab2.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE(l_tab2(j).serialnumber||' '||l_tab2(j).state ||' '||l_tab2(j).time1 ||' '||l_tab2(j).operatorid );
END LOOP;
END LOOP;
END;
/
quit;
我可以改进上述程序,还是有其他办法可以帮助我们完成这项工作?请帮忙。
答案 0 :(得分:2)
只需一次,您就可以用这个查询替换2个查询:
SELECT * FROM VSOWNERUPE07.VOUCHERHISTORYCLIENTV
WHERE serialnumber IN (SELECT DISTINCT serialnumber FROM
VOUCHERHISTORYCLIENTV WHERE at LIKE '&1');
并将输出写入最终文件。
您发现此问题有什么问题吗?
<强> UPDATE1 强>
首先,将它分解为2个不同的查询几乎从来都不是一个更好的解决方案.SQL上下文切换会杀了你。
分别在两个表的serialnumber
和at
列上构建索引,并尝试使用单个查询。
如果即便如此,你也可以试试UPDATE2。
<强> UPDATE2 强>
如果问题太多,请使用批量处理。 这个过程有点乏味,但旨在处理这种情况。
如何进行批量处理的一些示例包括here,here和here。
为此,您可能需要编写PLSQL过程。
在程序中,将所有数据批量收集到第一个查询中的varray中。
现在使用此varray运行第二个选择查询并收集数据。
接着
您可以将这些序列号放入,比如说另一个v阵列并将其写入文件
或
创建一个新的单列表并将其写入此新表。
然后将它写入文件/从perl分别查询这个新表。
注1:
如果您使用单独的表,请在每次运行后截断它;并在其上构建索引
注2:如果你对我所说的一无所知,请先查看这些链接。