ฉันมีฟังก์ชั่น PL / SQL (ทำงานบน Oracle 10g) ซึ่งฉันจะอัพเดตบางแถว มีวิธีการตรวจสอบว่ามีกี่แถวที่ได้รับผลกระทบจาก UPDATE หรือไม่ เมื่อดำเนินการแบบสอบถามด้วยตนเองมันจะบอกฉันว่ามีกี่แถวที่ได้รับผลกระทบฉันต้องการรับหมายเลขนั้นใน PL / SQL
ฉันมีฟังก์ชั่น PL / SQL (ทำงานบน Oracle 10g) ซึ่งฉันจะอัพเดตบางแถว มีวิธีการตรวจสอบว่ามีกี่แถวที่ได้รับผลกระทบจาก UPDATE หรือไม่ เมื่อดำเนินการแบบสอบถามด้วยตนเองมันจะบอกฉันว่ามีกี่แถวที่ได้รับผลกระทบฉันต้องการรับหมายเลขนั้นใน PL / SQL
คำตอบ:
คุณใช้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;
INSERT INTO
.. COMMIT
และยังอยู่ในขั้นตอนเดียวกันหลังจากแทรกฉันมีUPDATE SET WHERE EXISTS..COMMIT
แต่ฉันi := SQL%rowcount;
จะกลับแถวทั้งหมดแทนแถวที่มีการปรับปรุงเท่านั้น อาจเป็นอะไร
สำหรับผู้ที่ต้องการผลลัพธ์จากคำสั่งธรรมดาทางออกอาจเป็น:
begin
DBMS_OUTPUT.PUT_LINE(TO_Char(SQL%ROWCOUNT)||' rows affected.');
end;
ปัญหาพื้นฐานคือ SQL% ROWCOUNT เป็นตัวแปร PL / SQL (หรือฟังก์ชั่น) และไม่สามารถเข้าถึงได้โดยตรงจากคำสั่ง SQL ด้วยการใช้บล็อกที่ไม่ใช่ชื่อ PL / SQL สามารถทำได้
... หากใครมีวิธีแก้ปัญหาที่จะใช้ในคำสั่ง SELECT ฉันจะสนใจ
หรือSQL%ROWCOUNT
คุณสามารถใช้สิ่งนี้ภายในโพรซีเดอร์โดยไม่จำเป็นต้องประกาศตัวแปรใด ๆ
SQL%ROWCOUNT
สามารถใช้งานได้โดยไม่ได้รับมอบหมาย (อย่างน้อยจากOracle 11g )
ตราบใดที่ยังไม่มีการดำเนินการ (อัพเดทลบหรือแทรก) ภายในบล็อกปัจจุบันSQL%ROWCOUNT
ถูกตั้งค่าเป็น null จากนั้นจะอยู่กับจำนวนบรรทัดที่ได้รับผลกระทบจากการดำเนินการ DML ล่าสุด:
บอกว่าเรามีตารางลูกค้า
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
โปรดลองอันนี้ ..
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 ไคลเอนต์สำหรับ 1
ไคลเอ็นต์ที่ไม่มี 2 val_cli
ไม่มีไคลเอ็นต์ที่มี 3 val_cli
อัปเดต 1 ไคลเอ็นต์สำหรับ 4
ไคลเอ็นต์ที่ไม่มี 5 val_cli
อัปเดต 1 ไคลเอ็นต์สำหรับ 6
ไคลเอ็นต์ที่ไม่มี 7 val_cli
ไม่มีไคลเอ็นต์ที่มี 8 val_cli
ไม่มีไคลเอ็นต์ที่มี 9 val_cli
1 ไคลเอนต์ที่อัพเดตสำหรับ 10
จำนวนบรรทัดทั้งหมดที่มีผลต่อการดำเนินการอัพเดต: 5
ใช้ฟังก์ชั่นการวิเคราะห์ Count (*) OVER PARTITION BY NULL ซึ่งจะนับจำนวนแถวทั้งหมด