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

Truy cập động con trỏ theo tên cột

Bạn có thể sử dụng gói DBMS_SQL để tạo và truy cập con trỏ bằng các truy vấn động.

Tuy nhiên, việc truy cập một cột theo tên không thực sự đơn giản vì DBMS_SQL gói sử dụng định vị và trong một truy vấn động, chúng tôi có thể không biết thứ tự của các cột trước khi thực thi.

Hơn nữa, trong ngữ cảnh của câu hỏi này, có vẻ như chúng tôi không biết cột nào chúng tôi muốn hiển thị tại thời điểm biên dịch, chúng tôi sẽ giả định rằng cột chúng tôi muốn hiển thị được cung cấp dưới dạng tham số.

Chúng tôi có thể sử dụng DBMS_SQL.describe_columns để phân tích các cột của SELECT truy vấn sau khi nó đã được phân tích cú pháp để tạo ánh xạ động của các cột. Chúng tôi sẽ giả định rằng tất cả các cột có thể được chuyển thành VARCHAR2 vì chúng tôi muốn hiển thị chúng bằng DBMS_OUTPUT .

Đây là một ví dụ:

SQL> CREATE OR REPLACE PROCEDURE display_query_column(p_query VARCHAR2,
  2                                                   p_column VARCHAR2) IS
  3     l_cursor            INTEGER;
  4     l_dummy             NUMBER;
  5     l_description_table dbms_sql.desc_tab3;
  6     TYPE column_map_type IS TABLE OF NUMBER INDEX BY VARCHAR2(32767);
  7     l_mapping_table column_map_type;
  8     l_column_value  VARCHAR2(4000);
  9  BEGIN
 10     l_cursor := dbms_sql.open_cursor;
 11     dbms_sql.parse(l_cursor, p_query, dbms_sql.native);
 12     -- we build the column mapping
 13     dbms_sql.describe_columns3(l_cursor, l_dummy, l_description_table);
 14     FOR i IN 1 .. l_description_table.count LOOP
 15        l_mapping_table(l_description_table(i).col_name) := i;
 16        dbms_sql.define_column(l_cursor, i, l_column_value, 4000);
 17     END LOOP;
 18     -- main execution loop
 19     l_dummy := dbms_sql.execute(l_cursor);
 20     LOOP
 21        EXIT WHEN dbms_sql.fetch_rows(l_cursor) <= 0;
 22        dbms_sql.column_value(l_cursor, l_mapping_table(p_column), l_column_value);
 23        dbms_output.put_line(l_column_value);
 24     END LOOP;
 25     dbms_sql.close_cursor(l_cursor);
 26  END;
 27  /

Procedure created

Chúng ta có thể gọi thủ tục này bằng một truy vấn chỉ được biết tại thời điểm chạy:

SQL> set serveroutput on
SQL> exec display_query_column('SELECT * FROM scott.emp WHERE rownum < 5', 'ENAME');
SMITH
ALLEN
WARD
JONES

PL/SQL procedure successfully completed

SQL> exec display_query_column('SELECT * FROM scott.emp WHERE rownum < 5', 'EMPNO');
7369
7499
7521
7566

PL/SQL procedure successfully completed

Hãy thận trọng với SQL động:nó có các đặc quyền giống như người dùng và do đó có thể thực thi bất kỳ DML và DDL nào câu lệnh được phép cho lược đồ này.

Ví dụ:quy trình trên có thể được sử dụng để tạo hoặc thả một bảng:

SQL> exec display_query_column('CREATE TABLE foo(id number)', '');
begin display_query_column('CREATE TABLE foo(id number)', ''); end;
ORA-01003: aucune instruction analysée
ORA-06512: à "SYS.DBMS_SQL", ligne 1998
ORA-06512: à "APPS.DISPLAY_QUERY_COLUMN", ligne 13
ORA-06512: à ligne 1

SQL> desc foo
Name Type   Nullable Default Comments 
---- ------ -------- ------- -------- 
ID   NUMBER Y      


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ngày Oracle

  2. PIVOT dựa trên Oracle với nhiều nhóm cột

  3. Sự cố khi gặp lỗi Oracle Form Builder FRM-10044

  4. Làm thế nào để tránh lưu trữ thông tin đăng nhập để kết nối với Oracle bằng JDBC?

  5. Gọi một hàm với các tham số kiểu do người dùng xác định (Oracle ODP.NET)