Is it possible to use sql%rowcount for SELECT?

oracle, oracle10g, oracle11g, plsql, stored-procedures

Solution

Based on your comment

If 2nd 'select' query returns more than one row i want to take the first one and process with it

... 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. 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`.

If you want a different `outretvalue` for each `select` then you can wrap them in sub-blocks, each with their own exception handling section:

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. Depends what the exception condition means to you and your application though.

Problem

The code below may return more than one row. Will `sql%rowcount` return the number of rows fetched? ``` 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? ``` 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; ```

Original source