programing

SELECT에 sql%rowcount를 사용할 수 있습니까?

shortcode 2023. 9. 20. 21:12
반응형

SELECT에 sql%rowcount를 사용할 수 있습니까?

아래 코드는 하나 이상의 행을 반환할 수 있습니다.할 것이다sql%rowcount가져온 행 수를 반환하시겠습니까?

select * from emp where empname = 'Justin' and dept='IT'
if sql%rowcount>0
    ...

이것은 제 샘플 절차입니다. 제가 사용하고 있는 것입니다.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;

예, 사용 가능합니다.SQL%ROWCOUNT. PL/SQL에서 유효합니다.

그러나 PL/SQL에서 쿼리 결과는 PL/SQL 테이블과 같은 곳으로 이동해야 합니다.PL/SQL은 결과를 출력(단말기, 윈도우 등)으로 절대 전송하지 않습니다.SELECT * FROM안 될 겁니다

코드는 다음과 같습니다.

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;
/

업데이트:

업데이트된 질문은 다른 것을 찾고 있음을 나타냅니다.

옵션 1: 예외 사용

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;

옵션 2: 집계 사용

집계를 사용하면 쿼리는 항상 한 행만 반환합니다.이제 소스 행이 WHERE 절과 일치하면 두 결과 값이 모두 NULL이 되고, WHERE 절이 둘 이상의 행과 일치하면 최대값이 됩니다.

이 쿼리는 원래 같은 행에 없었던 포트 번호와 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;

옵션 3: ROWNUM 사용

이 쿼리는 최대 한 행을 반환합니다.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;

당신의 의견에 근거하여

두 번째 '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
    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어떻게 해야할지 결정합니다.예외 조건이 사용자와 응용프로그램에 어떤 의미를 갖는지에 따라 달라집니다.

언급URL : https://stackoverflow.com/questions/13395131/is-it-possible-to-use-sqlrowcount-for-select

반응형