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

Các hành vi kỳ lạ với con trỏ lồng nhau trong oracle

Như đã đề cập trong nhận xét về câu hỏi trước của bạn , con trỏ thứ hai của bạn không bị giới hạn đối với nhân viên được con trỏ đầu tiên tìm thấy vì bạn không có liên kết nào giữa chúng. Nơi bạn có:

and employee_id = employee_id

... cả hai đều tham chiếu đến cột bảng nên nó hoàn toàn không hoạt động như một bộ lọc. Bạn đã đặt cùng tên cho biến cục bộ của mình, điều này khiến mọi thứ nhầm lẫn, nhưng dù sao thì nó cũng nằm ngoài phạm vi - con trỏ này không hiển thị giá trị biến được đặt trong phần chính của thủ tục.

Bạn cần thực hiện một số việc như:

CREATE OR REPLACE PROCEDURE sp_run_employee_updates (p_date IN DATE) IS
    update_sql varchar2(4000);
    first_update boolean;

    CURSOR c_employees IS
        SELECT DISTINCT employee_id
        FROM bi_employee_update
        WHERE effective_date = p_date
        AND executed = 'N' 
        AND activity_id = '0';

    CURSOR c_updates(cp_employee_id bi_employee_update.employee_id%TYPE) IS
        SELECT *
        FROM bi_employee_update
        WHERE effective_date = p_date
        AND executed = 'N' 
        AND activity_id = '0'
        AND employee_id = cp_employee_id
        FOR UPDATE;

BEGIN
    -- loop around all employees with pending records
    FOR r_employee IN c_employees LOOP
        -- reset the update_sql variable to its base
        update_sql :=  'UPDATE BI_EMPLOYEE SET ';
        -- reset the flag so we only add the comments etc. on the first record
        first_update := true;

        -- loop around all pending records for this employee
        FOR r_update IN c_updates(r_employee.employee_id) LOOP
            -- add the comments etc., only for the first update we see
            if first_update then
                update_sql := update_sql
                    || ' comments = ''' || r_update.comments || ''','
                    || ' updated_by = ''' || r_update.changed_by  || ''','
                    || ' updated_on  = ''' || r_update.changed_on ||  ''','
                    || ' effective_date = ''' || r_update.effective_date  || '''';  
                first_update := false;
            end if;

            -- add the field/value from this record to the variable
            update_sql := update_sql || ', '
                || r_update.column_name || ' = ''' || r_update.new_value || '''' ; 

            -- mark this update as executed
            UPDATE bi_employee_update
            SET executed = 'Y'
            WHERE CURRENT OF c_updates;

        END LOOP;

        -- apply this update to the bi_employee record
        update_sql := update_sql || ' WHERE emp_id = ' || r_employee.employee_id;

        DBMS_OUTPUT.PUT_LINE(update_sql);
        EXECUTE IMMEDIATE update_sql; 
    END LOOP;
END sp_run_employee_updates;

Sự khác biệt quan trọng, thực sự, là con trỏ thứ hai bây giờ có một tham số và ID nhân viên từ con trỏ đầu tiên được chuyển dưới dạng tham số đó.

Ngoài ra, IN_DATE được khai báo là một ngày, vì vậy bạn không cần phải chuyển nó qua TO_DATE() . Sẽ có những chuyển đổi ngày tiềm ẩn ở những nơi khác (ngày có hiệu lực, v.v.) bởi vì bạn đang coi chúng là chuỗi, nhưng miễn là chúng không có thành phần thời gian, điều này có thể sẽ không phá vỡ bất cứ điều gì vì nó phải nhất quán trong thủ tục.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cố gắng không cần hai giải pháp riêng biệt cho chương trình x86 và x64

  2. Sao lưu cơ sở dữ liệu Oracle:Loại chiến lược sao lưu và dự phòng

  3. SQL Điền vào dữ liệu riêng biệt và một chuỗi

  4. Bảng bên ngoài Oracle:Bố cục tệp phẳng nâng cao

  5. Nhận kế hoạch thực thi thực tế trong Oracle 11g