Chr*_*mes 9 oracle stored-procedures exception
我有一个数据库表,我或多或少像一个队列.我正在尝试从中获取单个项目.这是有效的,除非SELECT..INTO失败(如果队列中只有一个项目,并且不同机器上的两个用户尝试并获取它,则可能会发生这种情况;只有一个将获胜).
这导致了熟悉的ORA-01403:没有找到数据异常.我试图更改SP,以便它在这种情况下返回NULL记录 - 同样的结果你得到它一个查询无法找到任何记录 - 但无济于事.我在这里做错了.
PROCEDURE sp_GetNextEmailFromQueue (pAgentId IN NUMBER, pRecs OUT recordSet)
IS
EMAIL_ID INTEGER;
BEGIN
SELECT id INTO EMAIL_ID FROM
(SELECT id, is_replied_to, is_being_worked, date_received
FROM SSQ_EMAILS
WHERE is_replied_to = 0 AND is_being_worked =0
ORDER BY date_received ASC)
WHERE rownum = 1;
UPDATE SSQ_EMAILS x
SET x.is_being_worked = 1,
x.agent_id = pAgentId,
x.work_started_date = SYSDATE
WHERE x.id = EMAIL_ID;
OPEN pRecs FOR
SELECT x.id,
x.message_id,
x.to_email,
x.from_email,
x.subject,
x.message,
x.date_received,
x.href_link,
x.is_being_worked,
x.work_started_date,
x.is_replied_to
FROM SSQ_EMAILS x
WHERE x.id = EMAIL_ID;
EXCEPTION
WHEN no_data_found
THEN
OPEN pRecs FOR
SELECT NULL
FROM SSQ_EMAILS;
END;
Run Code Online (Sandbox Code Playgroud)
我将异常处理程序放在实际导致错误抛出的代码片段周围.如果email_id为NULL,UPDATE则不会更新任何行,并且SELECT不会返回任何行.
PROCEDURE sp_GetNextEmailFromQueue (pAgentId IN NUMBER, pRecs OUT recordSet)
IS
EMAIL_ID INTEGER;
BEGIN
BEGIN
SELECT id
INTO EMAIL_ID
FROM (SELECT id, is_replied_to, is_being_worked, date_received
FROM SSQ_EMAILS
WHERE is_replied_to = 0 AND is_being_worked =0
ORDER BY date_received ASC)
WHERE rownum = 1;
EXCEPTION
WHEN no_data_found
THEN
email_id := null;
END;
UPDATE SSQ_EMAILS x
SET x.is_being_worked = 1,
x.agent_id = pAgentId,
x.work_started_date = SYSDATE
WHERE x.id = EMAIL_ID;
OPEN pRecs FOR
SELECT x.id,
x.message_id,
x.to_email,
x.from_email,
x.subject,
x.message,
x.date_received,
x.href_link,
x.is_being_worked,
x.work_started_date,
x.is_replied_to
FROM SSQ_EMAILS x
WHERE x.id = EMAIL_ID;
END;
Run Code Online (Sandbox Code Playgroud)
但请注意,此代码不会阻止两个不同的调用者在同一行上工作.如果两个会话同时调用此过程,则两者都完全可能选择同一行.如果要防止这种情况,则SELECT需要使用FOR UPDATE子句锁定它所选择的行.
小智 4
在这种情况下你什么也做不了:
exception
when no_data_found then
null;
end;
Run Code Online (Sandbox Code Playgroud)
这会返回 null 对pRecs吧?
编辑
第二种方法:
cursor c_mail is
SELECT id
FROM
(SELECT id, is_replied_to, is_being_worked, date_received
FROM SSQ_EMAILS
WHERE is_replied_to = 0 AND is_being_worked =0
ORDER BY date_received ASC)
WHERE rownum = 1;
....
open c_mail;
fetch c_mail into email_id; -- no_data_found not happens
close c_mail;
Run Code Online (Sandbox Code Playgroud)