存储过程中的光标完成并卡住(Oracle Linux VM 上的 Oracle 11g)
Posted
技术标签:
【中文标题】存储过程中的光标完成并卡住(Oracle Linux VM 上的 Oracle 11g)【英文标题】:Cursor in stored procedure finishes and get stuck (Oracle 11g on Oracle Linux VM) 【发布时间】:2015-05-06 20:35:13 【问题描述】:我在 Oracle VM VirutalBox 中安装了 Oracle Linux 11g。 (分配 4GB RAM) 我有一个有几个表的用户。我在这个用户的模式中创建了一个使用游标的过程:
CREATE OR REPLACE PROCEDURE SHOW_STATS (p_emp_id IN number)
IS
v_name varchar2(50);
CURSOR c_stat IS
SELECT J.IS_DESCRIPTION as st_name, count(*) AS st_count
FROM inventory I , inventory_status J
WHERE I.STATUS=J.IS_ID and I.EMPLOYEE_ID = p_emp_id
GROUP BY J.IS_DESCRIPTION;
c_stat_rec c_stat%rowtype;
BEGIN
IF NOT c_stat%ISOPEN THEN
OPEN c_stat;
END IF;
SELECT first_name || ' ' || last_name
INTO v_name
FROM employees
WHERE employee_id = p_emp_id;
DBMS_OUTPUT.PUT_LINE ('Employee ' || v_name || ' Stats:');
DBMS_OUTPUT.PUT_LINE ('-----------------------------------------');
LOOP
FETCH c_stat INTO c_stat_rec ;
EXIT WHEN c_stat%NOTFOUND ;
DBMS_OUTPUT.PUT_LINE (c_stat_rec.st_count || ' items in status ' || c_stat_rec.st_name);
END LOOP;
END;
程序编译成功。 当我在笔记本电脑(Win8)上的 PL/SQL Developer 上测试该过程时 - 它在运行该过程后卡住了。即,当我通过一个简单的块进行测试时:
begin
-- Call the procedure
show_stats(10004);
end;
我已经在游标中尝试了 SELECT 语句 - 它运行并给出输出。
调试运行正常(由于某种原因,没有输出),但是当它退出该过程时,我得到了沙观察处理,PL/SQL 客户端卡住了,我不得不让它崩溃。
任何人都可以找到它发生的原因吗?
【问题讨论】:
您从哪个窗口运行调用,您是否看到任何 dbms_output?如果你看到那里有什么,如果你在循环之后添加另一条消息,你看到了吗?最后关闭光标有什么不同吗? (它不应该,但也许这会让调试器感到困惑?)你能从另一个客户端运行它吗,比如 VM 中的 SQL*Plus? 我运行 Windows 8.1 我没有看到任何 DBMS_OUTPUT 输出,这也让我感到困惑。关闭光标没有任何效果。当我从 VM 中的 sql*plus 运行该块时,我只收到一条消息,表明该块已成功编译 更新:当我从 SQL*Plus 运行块时,当我执行 'Exec show_stats();' 时,我确实看到了结果(我忘记设置服务器输出)。当我在 Windows 上运行 sql plus 时也是如此。所以 - 问题是,为什么 pl/sql 会卡住 我指的是哪个 PL/SQL Developer 窗口(SQL、命令、测试...我没有运行它,所以不记得其他的)而不是哪个版本的 Windows。你现在也看到那里的输出了吗?否则你为什么认为它在程序之后卡住了,而不是在循环中,说(也不应该卡在那里)。 它确实看起来像一个 PL/SQL 错误,但我对它还不够熟悉,无法识别它或提供太多帮助 - 主要是希望梳理出信息,以便其他人可以加入。只是删除所有 dbms_output 调用有什么不同吗?我已经更改了标签,希望能得到更合适的关注。祝你好运。 【参考方案1】:您需要以/
结束您的程序
PLSQL code
END;
/
【讨论】:
程序编译成功,并从其他客户端(包括同一客户端的更高版本)运行,所以不是问题。【参考方案2】:你为什么不用这样的光标?
CREATE OR REPLACE PROCEDURE SHOW_STATS (p_emp_id IN number)
is
v_name varchar2(100);
begin
SELECT first_name || ' ' || last_name
INTO v_name
FROM employees
WHERE employee_id = p_emp_id;
for i in (
SELECT J.IS_DESCRIPTION as st_name, count(*) AS st_count
FROM inventory I , inventory_status J
WHERE I.STATUS=J.IS_ID and I.EMPLOYEE_ID = p_emp_id
GROUP BY J.IS_DESCRIPTION) loop
end loop;
exception
when others then
dbms_output.put_line(sqlerrm);
end;
因此您不必担心关闭不在您的程序中的光标
【讨论】:
以上是关于存储过程中的光标完成并卡住(Oracle Linux VM 上的 Oracle 11g)的主要内容,如果未能解决你的问题,请参考以下文章
在 Oracle -17110 中创建存储过程 - 警告:执行完成并出现警告