[英]Is it possible to use sql%rowcount for SELECT?
The code below may return more than one row. 下面的代码可能会返回多行。 Will
sql%rowcount
return the number of rows fetched? 请问
sql%rowcount
返回获取的行数?
select * from emp where empname = 'Justin' and dept='IT'
if sql%rowcount>0
...
This is my sample proc; 这是我的样本过程; am I using
sql%rowcount
in correct way? 我以正确的方式使用
sql%rowcount
吗?
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';
if outInststatus = 'Y' then
select PORT_NUMBER,STATIC_IP into outport,outIP from TINST where INST_ID = in_Hid and IP_PORT_STATUS = 'Y';
if sql%rowcount >= 1 then
select SOCK_ID into outSockid from TINST where PORT_NUMBER = outport AND STATIC_IP = outIP;
outretvalue := 0;
else
outretvalue := -12;
end if;
EXCEPTION
WHEN NO_DATA_FOUND THEN
outretvalue := -13;
end if;
END;
Yes, you can use SQL%ROWCOUNT
. 是的,您可以使用
SQL%ROWCOUNT
。 It's valid in PL/SQL. 它在PL / SQL中有效。
However, in PL/SQL the result of your query needs to go somewhere eg into a PL/SQL table. 但是,在PL / SQL中,查询的结果需要转移到某个PL / SQL表中。 PL/SQL will never send the result to the output (terminal, window etc.).
PL / SQL永远不会将结果发送到输出 (终端,窗口等)。 So
SELECT * FROM
won't work. 所以
SELECT * FROM
不起作用。
Your code could look like this: 您的代码可能如下所示:
DECLARE
TYPE emp_t ...;
emp_tab emp_t;
BEGIN
SELECT *
BULK COLLECT INTO emp_tab
FROM emp
WHERE empname = 'Justin' AND dept='IT';
IF sql%rowcount > 0 THEN
.. do something ...
END IF;
END;
/
Update : 更新 :
The updated questions suggests that you're looking for something else. 更新的问题表明您正在寻找其他东西。
Option 1: Use exceptions 选项1:使用例外
If there are 0 rows or more than 1 row, these cases are handled separately (as errors): 如果有0行或多于1行,则这些情况将单独处理(作为错误):
BEGIN
select PORT_NUMBER,STATIC_IP into outport, outIP
from TINST
where INST_ID = in_Hid AND IP_PORT_STATUS = 'Y';
EXCEPTION
WHEN NO_DATA_FOUND THEN
outretvalue := -12;
RETURN;
WHEN TOO_MANY_ROWS THEN
outretvalue := -13;
RETURN;
END;
Option 2: Use aggregations 选项2:使用聚合
Using aggregations, the query will always return exactly one row. 使用聚合,查询将始终返回一行。 If now source row matched the WHERE clause, then both result values will be NULL.
如果现在源行与WHERE子句匹配,则两个结果值都将为NULL。 If there WHERE clause matched more than one row, the maximum will be taken.
如果WHERE子句匹配多行,则将采用最大值。
Note that this query might return a port number and an IP address that originally were not on the same row. 请注意,此查询可能会返回端口号和最初不在同一行的IP地址。
select MAX(PORT_NUMBER), MAX(STATIC_IP) into outport, outIP
from TINST
where INST_ID = in_Hid AND IP_PORT_STATUS = 'Y';
IF outport IS NULL OR outIP IS NULL THEN
outretvalue := -12;
RETURN;
END IF;
Option 3: Use ROWNUM 选项3:使用ROWNUM
This query returns at most one row. 此查询最多返回一行。 If no row matched the WHERE clause, an exception is thrown and needs to be handled:
如果没有与WHERE子句匹配的行,则抛出异常并需要处理:
BEGIN
select PORT_NUMBER, STATIC_IP into outport, outIP
from TINST
where INST_ID = in_Hid AND IP_PORT_STATUS = 'Y'
AND ROWNUM = 1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
outretvalue := -12;
RETURN;
END;
Based on your comment 根据您的评论
If 2nd 'select' query returns more than one row i want to take the first one and process with it
如果第二个'select'查询返回多行,我想取第一个并用它处理
... this ought to work, but perhaps not quite as you expect, as you haven't defined what the 'first one' means. ......这应该有效,但也许并不像你期望的那样,因为你没有定义“第一个”的含义。
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;
The exception
handler applies to the whole block . exception
处理程序适用于整个块 。 If any of the select
statements find no rows, the no_data_found
exception will be handled by that block and will set outretvalue
to -12
. 如果任何
select
语句没有找到任何行,则no_data_found
异常将由该块处理,并将outretvalue
设置为-12
。
If you want a different outretvalue
for each select
then you can wrap them in sub-blocks, each with their own exception handling section: 如果你想为每个
select
不同的outretvalue
,那么你可以将它们包装在子块中,每个子块都有自己的异常处理部分:
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;
You only need to do that if the caller needs to know which select
failed, and if you never really expect any of them to fail then it's probably more common not to catch the exception at all and let the caller see the raw no_data_found
and decide what to do. 如果调用者需要知道哪个
select
失败,你只需要这样做,如果你真的没有想到它们中的任何一个失败那么可能更常见的是根本不捕获异常并让调用者看到原始的no_data_found
并决定什么去做。 Depends what the exception condition means to you and your application though. 取决于异常条件对您和您的应用程序的意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.