sql >> Databasteknik >  >> RDS >> Oracle

Öppna markören efter kolumnnamn dynamiskt

Du kan använda paketet DBMS_SQL för att skapa och komma åt markörer med dynamiska frågor.

Det är dock inte riktigt enkelt att komma åt en kolumn med namn eftersom DBMS_SQL paketet använder positionering och i en dynamisk fråga kanske vi inte känner till kolumnernas ordning innan körningen.

Vidare, i samband med denna fråga, verkar det som att vi kanske inte vet vilken kolumn vi vill visa vid kompilering, vi kommer att anta att kolumnen vi vill visa ges som en parameter.

Vi kan använda DBMS_SQL.describe_columns för att analysera kolumnerna i en SELECT fråga efter att den har analyserats för att bygga en dynamisk mappning av kolumnerna. Vi antar att alla kolumner kan gjutas till VARCHAR2 eftersom vi vill visa dem med DBMS_OUTPUT .

Här är ett exempel:

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 anropa denna procedur med en fråga som endast är känd vid körning:

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

Var försiktig med dynamisk SQL:den har samma privilegier som användaren och kan därför köra valfri DML och DDL sats tillåten för detta schema.

Till exempel kan proceduren ovan användas för att skapa eller släppa en tabell:

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. Fick felet "ogiltigt antal repetitioner" från regexp

  2. Gå med i set-returning function (SRF) och åtkomstkolumner i SQLAlchemy

  3. MySQL-frågan försvinner inte efter att ha dödats

  4. Vilken MySQL-kollation jämför t.ex. é och e lika?