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

làm thế nào để khai báo% ROWTYPE của một biến SYS_REFCURSOR được nhập yếu?

Câu trả lời ngắn gọn là, bạn không thể. Bạn cần xác định một biến cho mỗi cột sẽ được trả về.

DECLARE
    P_RS SYS_REFCURSOR;
    L_T_COL1 T.COL1%TYPE;
    L_T_COL1 T.COL2%TYPE;
    ...

Và sau đó tìm nạp vào danh sách các cột:

FETCH P_RS INTO L_T_COL1, L_T_COL2, ... ;

Điều này gây đau đớn nhưng có thể kiểm soát được miễn là bạn biết mình đang mong đợi điều gì ở con trỏ tham chiếu. Sử dụng T.* trong thủ tục của bạn làm cho điều này trở nên mỏng manh, vì việc thêm một cột vào bảng sẽ phá vỡ mã nghĩ rằng nó biết có những cột nào và thứ tự của chúng. (Bạn cũng có thể phá vỡ nó giữa các môi trường nếu các bảng không được tạo nhất quán - Tôi đã thấy những nơi mà thứ tự cột khác nhau trong các môi trường khác nhau). Có thể bạn sẽ muốn đảm bảo rằng mình chỉ chọn những cột mà bạn thực sự quan tâm, để tránh phải xác định các biến cho những thứ bạn sẽ không bao giờ đọc.

Từ 11g, bạn có thể sử dụng DBMS_SQL gói để chuyển đổi sys_refcursor của bạn thành một DBMS_SQL và bạn có thể thẩm vấn con trỏ đó để xác định các cột. Chỉ là một ví dụ về những gì bạn có thể làm, điều này sẽ in ra giá trị của mọi cột trong mọi hàng, với tên cột:

DECLARE
    P_RS SYS_REFCURSOR;
    L_COLS NUMBER;
    L_DESC DBMS_SQL.DESC_TAB;
    L_CURS INTEGER;
    L_VARCHAR VARCHAR2(4000);
BEGIN
    CAPITALEXTRACT(P_RS => P_RS);
    L_CURS := DBMS_SQL.TO_CURSOR_NUMBER(P_RS);
    DBMS_SQL.DESCRIBE_COLUMNS(C => L_CURS, COL_CNT => L_COLS,
        DESC_T => L_DESC);

    FOR i IN 1..L_COLS LOOP
        DBMS_SQL.DEFINE_COLUMN(L_CURS, i, L_VARCHAR, 4000);
    END LOOP;

    WHILE DBMS_SQL.FETCH_ROWS(L_CURS) > 0 LOOP
        FOR i IN 1..L_COLS LOOP
            DBMS_SQL.COLUMN_VALUE(L_CURS, i, L_VARCHAR);
            DBMS_OUTPUT.PUT_LINE('Row ' || DBMS_SQL.LAST_ROW_COUNT
                || ': ' || l_desc(i).col_name
                || ' = ' || L_VARCHAR);
        END LOOP;
    END LOOP;

    DBMS_SQL.CLOSE_CURSOR(L_CURS);
END;
/

Điều đó không được sử dụng nhiều trong thực tế, và để ngắn gọn, tôi đang coi mọi giá trị là một chuỗi vì dù sao thì tôi cũng chỉ muốn in nó ra. Xem các tài liệu và tìm kiếm các ví dụ để có các ứng dụng thực tế hơn.

Nếu bạn chỉ muốn một vài cột từ con trỏ tham chiếu của mình, bạn có thể, tôi cho là lặp lại l_desc và ghi lại vị trí mà column_name là bất cứ điều gì bạn quan tâm, dưới dạng một biến số; sau đó bạn có thể tham chiếu đến cột bằng biến đó sau này, nơi bạn thường sử dụng tên trong vòng lặp con trỏ. Phụ thuộc vào những gì bạn đang làm với dữ liệu.

Nhưng trừ khi bạn đang mong đợi để không biết thứ tự cột mà bạn đang lấy lại, điều này khó xảy ra vì bạn dường như kiểm soát quy trình - và giả sử bạn thoát khỏi .* s - bạn có lẽ tốt hơn nhiều nên giảm các cột trả về đến mức tối thiểu bạn cần và chỉ cần khai báo tất cả chúng riêng lẻ.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SID khác với tên dịch vụ như thế nào trong Oracle tnsnames.ora

  2. Làm cách nào để tôi có thể sử dụng regex để chia một chuỗi, sử dụng một chuỗi làm dấu phân cách?

  3. Dấu thời gian ngủ đông với múi giờ

  4. CHÈN và CẬP NHẬT bản ghi bằng cách sử dụng con trỏ trong oracle

  5. Oracle ngày giữa truy vấn