PL / SQL에서 UPDATE의 영향을받는 행 수


162

일부 행을 업데이트하는 PL / SQL 기능 (Oracle 10g에서 실행)이 있습니다. UPDATE의 영향을받는 행 수를 확인하는 방법이 있습니까? 쿼리를 수동으로 실행할 때 영향을받는 행 수를 알려면 PL / SQL에서 해당 숫자를 얻고 싶습니다.

답변:


245

sql%rowcount변수를 사용합니다 .

영향을받는 행 수를 찾아야하는 명령문 다음에 바로 호출해야합니다.

예를 들면 다음과 같습니다.

set serveroutput ON; 
DECLARE 
    i NUMBER; 
BEGIN 
    UPDATE employees 
    SET    status = 'fired' 
    WHERE  name LIKE '%Bloggs'; 
    i := SQL%rowcount; 
    --note that assignment has to precede COMMIT
    COMMIT; 
    dbms_output.Put_line(i); 
END; 

4
할당은 모든 COMMIT보다 우선해야합니다
rshdev

@Clive INSERT INTO.. 로 프로 시저를 얻었 COMMIT으며 삽입 후 동일한 프로 시저 에서을 가지고 UPDATE SET WHERE EXISTS..COMMIT있지만 i := SQL%rowcount;업데이트 된 행 대신 모든 행을 반환합니다. 무엇이 될 수 있습니까?
Guilherme Matheus

26

일반 명령의 결과를 원하는 사람들에게 해결책은 다음과 같습니다.

begin
  DBMS_OUTPUT.PUT_LINE(TO_Char(SQL%ROWCOUNT)||' rows affected.');
end;

기본적인 문제점은 SQL % ROWCOUNT가 PL / SQL 변수 (또는 함수)이며 SQL 명령에서 직접 액세스 할 수 없다는 것입니다. noname PL / SQL 블록을 사용하면이를 달성 할 수 있습니다.

... 누구든지 SELECT 명령에서 사용할 솔루션이 있다면 관심이 있습니다.


6

또는 SQL%ROWCOUNT 변수를 선언 할 필요없이 프로 시저 내에서이를 사용할 수 있습니다


4
당신은 할 필요가 - SQL의 %의 ROWCOUNT 함수, 당신은 단지 "사용"할 수있다 그것으로 무언가를 - 변수에 저장, 또는 다른 프로 시저에 입력으로 보내거나 다른 일에 추가할지 여부를 지정합니다.
Jeffrey Kemp

8
Ali H의 요점은 행 수에 영향을 줄 다른 SQL 문이있을 때까지 변수에 변수를 할당 할 필요가 없다는 것입니다. 즉, 나중에 누군가 SQL 문을 호출하기 전에 다른 SQL 문을 추가 해야하는 버그를 피하기 위해 변수에 변수를 할당해야한다는 데 동의합니다. 그리고 Ali H의 답변은 별도의 답변으로 게시 된 것이 아니라 Clive의 답변에 대한 의견이어야합니다.
Kirby

1

SQL%ROWCOUNT할당되지 않은 상태에서도 사용할 수 있습니다 (적어도 Oracle 11g 이상 ).

현재 블록 내에서 조작 (업데이트, 삭제 또는 삽입)이 수행되지 않은 한 SQL%ROWCOUNT널 (null)로 설정됩니다. 그런 다음 마지막 DML 작업의 영향을받는 줄 수를 유지합니다.

CLIENT 테이블이 있다고 해

create table client (
  val_cli integer
 ,status varchar2(10)
)
/

우리는 이것을 다음과 같이 테스트 할 것입니다 :

begin
  dbms_output.put_line('Value when entering the block:'||sql%rowcount);

  insert into client 
            select 1, 'void' from dual
  union all select 4, 'void' from dual
  union all select 1, 'void' from dual
  union all select 6, 'void' from dual
  union all select 10, 'void' from dual;  
  dbms_output.put_line('Number of lines affected by previous DML operation:'||sql%rowcount);

  for val in 1..10
    loop
      update client set status = 'updated' where val_cli = val;
      if sql%rowcount = 0 then
        dbms_output.put_line('no client with '||val||' val_cli.');
      elsif sql%rowcount = 1 then
        dbms_output.put_line(sql%rowcount||' client updated for '||val);
      else -- >1
        dbms_output.put_line(sql%rowcount||' clients updated for '||val);
      end if;
  end loop;  
end;

를 야기하는:

Value when entering the block:
Number of lines affected by previous DML operation:5
2 clients updated for 1
no client with 2 val_cli.
no client with 3 val_cli.
1 client updated for 4
no client with 5 val_cli.
1 client updated for 6
no client with 7 val_cli.
no client with 8 val_cli.
no client with 9 val_cli.
1 client updated for 10

-1

이것을 시도하십시오 ..


create table client (
  val_cli integer
 ,status varchar2(10)
);

---------------------
begin
insert into client
select 1, 'void' from dual
union all
select 4, 'void' from dual
union all
select 1, 'void' from dual
union all
select 6, 'void' from dual
union all
select 10, 'void' from dual;
end;

---------------------
select * from client;

---------------------
declare
  counter integer := 0;
begin
  for val in 1..10
    loop
      update client set status = 'updated' where val_cli = val;
      if sql%rowcount = 0 then
        dbms_output.put_line('no client with '||val||' val_cli.');
      else
        dbms_output.put_line(sql%rowcount||' client updated for '||val);
        counter := counter + sql%rowcount;
      end if;
  end loop;
   dbms_output.put_line('Number of total lines affected update operation: '||counter);
end;

---------------------
select * from client;

--------------------------------------------------------

결과는 다음과 같습니다.


2
val_cli를 가진 클라이언트가없는 1 명의 클라이언트 2 명이 업데이트되었습니다 .
3 val_cli를 가진 클라이언트가 없습니다.
4
val_cli로 클라이언트가없는 4 명의 클라이언트 1 개가 업데이트되었습니다 .
6
val_cli의 클라이언트가없는 6 명의 클라이언트 1 개가 업데이트되었습니다 .
8 val_cli를 가진 클라이언트가 없습니다.
val_cli가 9 인 클라이언트가 없습니다.
클라이언트 1 개 업데이트 10 개
업데이트 작업에 영향을받는 총 줄 수 : 5



솔루션에 의견을 추가하십시오. 구체적으로 설명하십시오.
Kumar Abhishek

-3

Count (*) 분석 함수를 사용하십시오. OVER PARTITION BY NULL 총 행 수를 계산합니다.


실제로 업데이트 한 항목의 수를 확인하면 업데이트 문을 실행 한 후 일반적인 해결책을 제공하지 않습니다. 예를 들어, 테이블 T에 모든 값으로 "1"을 포함하는 하나의 열 c1이 있고 해당 열의 모든 행을 "2"로 업데이트하면 null 도움말로 분할하는 방법은 무엇입니까?
nanosoft
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.