根据您的评论
如果第二个“选择”查询返回不止一行,我想取第一行并处理它
...这应该可以工作,但可能并不像您期望的那样,因为您尚未定义“第一个”的含义。
CREATE PROCEDURE Procn(in_Hid IN VARCHAR2, outInststatus OUT VARCHAR2,
outSockid IN NUMBER, outport OUT VARCHAR2, outIP OUT VARCHAR2,
outretvalue OUT NUMBER)
AS
BEGIN
select INST_STATUS into outInststatus
from TINST_child
where INST_ID = in_Hid and INST_STATUS = 'Y';
-- no need to check if outInstatus is Y, that's all it can be here
-- restricting with `rownum` means you'll get at most one row, so you will
-- not get too_many_rows. But it will be an arbitrary row - you have no
-- criteria to determine which of the multiple rows you want. And you can
-- still get no_data_found which will go to the same exception and set -12
select PORT_NUMBER, STATIC_IP into outport, outIP
from TINST
where INST_ID = in_Hid and IP_PORT_STATUS = 'Y'
and rownum < 2;
-- no need to check sql%rowcount; it can only be 1 here
-- not clear if this can return multiple rows too, and what should happen
-- if it can; could use rownum restriction but with the same caveats
select SOCK_ID into outSockid
from TINST
where PORT_NUMBER = outport AND STATIC_IP = outIP;
outretvalue := 0;
EXCEPTION
WHEN NO_DATA_FOUND THEN
outretvalue := -12;
END;
exception
处理程序适用于整个块。如果任何select
语句找不到行,则该no_data_found
异常将由该块处理并设置outretvalue
为-12
.
如果您想要outretvalue
每个不同的,select
那么您可以将它们包装在子块中,每个子块都有自己的异常处理部分:
CREATE PROCEDURE Procn(in_Hid IN VARCHAR2, outInststatus OUT VARCHAR2,
outSockid IN NUMBER, outport OUT VARCHAR2, outIP OUT VARCHAR2,
outretvalue OUT NUMBER)
AS
BEGIN
BEGIN
select INST_STATUS into outInststatus
from TINST_child
where INST_ID = in_Hid and INST_STATUS = 'Y';
EXCEPTION
WHEN NO_DATA_FOUND THEN
outretvalue := -12;
END;
BEGIN
select PORT_NUMBER, STATIC_IP into outport, outIP
from TINST
where INST_ID = in_Hid and IP_PORT_STATUS = 'Y'
and rownum < 2;
EXCEPTION
WHEN NO_DATA_FOUND THEN
outretvalue := -13;
END;
BEGIN
select SOCK_ID into outSockid
from TINST
where PORT_NUMBER = outport AND STATIC_IP = outIP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
outretvalue := -14;
END;
outretvalue := 0;
END;
您只需要在调用者需要知道哪个select
失败时才需要这样做,并且如果您从未真正期望它们中的任何一个失败,那么可能更常见的是根本不捕获异常并让调用者看到原始no_data_found
内容并决定做什么. 取决于异常条件对您和您的应用程序意味着什么。