sql >> Database teknologi >  >> RDS >> Oracle

Få adgang til markøren efter kolonnenavn dynamisk

Du kan bruge pakken DBMS_SQL at oprette og få adgang til markører med dynamiske forespørgsler.

Det er dog ikke rigtig ligetil at få adgang til en kolonne ved navn, fordi DBMS_SQL pakken bruger positionering, og i en dynamisk forespørgsel kender vi muligvis ikke rækkefølgen af ​​kolonnerne før udførelsen.

Ydermere, i forbindelse med dette spørgsmål, ser det ud til, at vi måske ikke ved, hvilken kolonne vi ønsker at vise på kompileringstidspunktet, vi vil antage, at den kolonne, vi ønsker at vise, er angivet som en parameter.

Vi kan bruge DBMS_SQL.describe_columns at analysere kolonnerne i en SELECT forespørgsel efter at den er blevet parset for at bygge en dynamisk kortlægning af kolonnerne. Vi vil antage, at alle kolonner kan castes ind i VARCHAR2 da vi ønsker at vise dem med DBMS_OUTPUT .

Her er et eksempel:

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

Vi kan kalde denne procedure med en forespørgsel, der kun kendes under kørsel:

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

Vær forsigtig med dynamisk SQL:den har de samme rettigheder som brugeren og kan derfor udføre enhver DML og DDL sætning tilladt for dette skema.

For eksempel kan ovenstående procedure bruges til at oprette eller slette en tabel:

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. Hvordan skriver man en (MySQL) LIMIT i SQL Server?

  2. Hibernate:hvad er forskellen mellem MySQLDialect og MySQLInnoDBDialect?

  3. Specialbygget statistik

  4. VÆLG * FRA tabel WHERE kolonne =1,2,3,4