Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

cập nhật bằng vòng lặp for trong plsql

Bạn không cần FOR LOOP , chỉ một CẬP NHẬT duy nhất hoạt động:

UPDATE emp
  SET comm = extra
WHERE comm IS NULL AND extra IS NOT NULL;

Đây là bản trình diễn: http://www.sqlfiddle.com/#!4/ aacc3 / 1

--- CHỈNH SỬA ----

Tôi không nhận thấy rằng trong đầu ra dự kiến, deptno 10 đã được cập nhật thành 20,
cập nhật deptno cần một truy vấn khác:

UPDATE emp
   SET deptno = 20
WHERE deptno = 10;



---- CHỈNH SỬA -----

Nếu bạn muốn chèn các giá trị đã thay đổi vào bảng khác, hãy thử quy trình với RETURNING..BULK COLLECT và FORALL:

CREATE OR REPLACE PROCEDURE pro_cedure( p_dept_id number  ) 
IS
      TYPE changed_table_type IS TABLE OF changed%ROWTYPE;
      changed_buff changed_table_type;
BEGIN
      SELECT deptno, comm, extra BULK COLLECT INTO changed_buff
      FROM emp
      WHERE comm IS NULL AND extra IS NOT NULL AND deptno = p_dept_id
      FOR UPDATE;
      UPDATE emp
      SET comm = extra
      WHERE comm IS NULL AND extra IS NOT NULL AND deptno = p_dept_id;
      FORALL i IN 1 .. changed_buff.count
        INSERT INTO changed VALUES changed_buff( i );
END;
/

Quy trình sẽ hoạt động nếu bạn không xử lý số lượng lớn bản ghi trong một lần gọi (hơn 1000 ... hoặc tối đa là vài nghìn). Nếu một dept_id có thể chứa mười nghìn hàng trở lên, thì quy trình này có thể chậm, vì nó sẽ tiêu tốn một lượng lớn bộ nhớ PGA. Trong trường hợp như vậy, cần có một cách tiếp cận khác với tập hợp hàng loạt theo khối.

- CHỈNH SỬA --- cách lưu trữ các giá trị trình tự -------

Tôi giả sử rằng bảng changed có 4 cột, như thế này:

  CREATE TABLE "TEST"."CHANGED" 
   (    "DEPTNO" NUMBER, 
        "OLDVAL" NUMBER, 
        "NEWVAL" NUMBER, 
        "SEQ_NEXTVAL" NUMBER 
   ) ;

và chúng tôi sẽ lưu trữ các giá trị trình tự trong seq_nextval cột.

Trong trường hợp này, thủ tục có thể giống như sau:

create or replace 
PROCEDURE pro_cedure( p_dept_id number  ) 
IS
      TYPE changed_table_type IS TABLE OF changed%ROWTYPE;
      changed_buff changed_table_type;
BEGIN
      SELECT deptno, comm, extra, sequence_name.nextval 
        BULK COLLECT INTO changed_buff
        FROM emp
        WHERE comm IS NULL AND extra IS NOT NULL AND deptno = p_dept_id
        FOR UPDATE;
      UPDATE emp
        SET comm = extra
        WHERE comm IS NULL AND extra IS NOT NULL AND deptno = p_dept_id;
      FORALL i IN 1 .. changed_buff.count
        INSERT INTO changed VALUES changed_buff( i );
END;



--- EDIT --- phiên bản có con trỏ cho các tập dữ liệu nhỏ -----

Có, đối với các nhóm dữ liệu nhỏ, việc thu thập dữ liệu hàng loạt không làm tăng tốc độ đáng kể và con trỏ đơn giản với for..loop là đủ trong trường hợp như vậy.
Dưới đây là ví dụ cách bạn sử dụng con trỏ cùng với cập nhật, hãy lưu ý FOR UPDATE mệnh đề này là bắt buộc khi chúng tôi dự định cập nhật bản ghi được tìm nạp từ con trỏ bằng cách sử dụng WHERE CURRENT OF mệnh đề.
Lần này giá trị trình tự được đánh giá trong câu lệnh INSERT.

create or replace 
PROCEDURE pro_cedure( p_dept_id number  ) 
IS
      CURSOR mycursor IS 
         SELECT deptno, comm, extra
         FROM emp
         WHERE comm IS NULL AND extra IS NOT NULL 
               AND deptno = p_dept_id
         FOR UPDATE;    
BEGIN
      FOR emp_rec IN  mycursor
      LOOP
         UPDATE emp 
            SET comm = extra
            WHERE CURRENT OF mycursor;
         INSERT INTO changed( deptno, oldval, newval, seq_nextval)
                VALUES( emp_rec.deptno, emp_rec.comm, 
                        emp_rec.extra, sequence_name.nextval );
      END LOOP;
END;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Những thay đổi chính về Công nghệ trong E-Business Suite 12.2

  2. Có phải xmlparserv2 từ com.oracle.jdbc:ojdbc8 (v12.2.0.1) đột ngột bị hỏng không?

  3. Làm thế nào để bao gồm các tệp jar vào một Thủ tục lưu trữ Java trong Oracle?

  4. Làm cách nào để ghi / theo dõi các lệnh gọi thủ tục được lưu trữ của Oracle với các giá trị tham số?

  5. hàm listunagg?