views:

627

answers:

2

Is there an Oracle function to return the data type of the parameter?

Alternatively, what is the easiest way to determine the data type of all columns in a query that I've written?

+6  A: 

The Dump Function:

returns a VARCHAR2 value containing the datatype code, length in bytes, and internal representation of expr. The returned result is always in the database character set. For the datatype corresponding to each code, see Table 2-1.

borjab
And to think... I wrote a PL/SQL program to dump the results of a query into a temporary table, then read the information back from USER_TABLE_COLUMNS.
GameFreak
+2  A: 

If you've written a query, you could create a view based on it and then query the data dictionary to see what the columns' data types are:

create view vw_test as
select 1       an_integer,
       'abc'   a_string,
       sysdate a_date
from dual;

desc vw_test;

Name        Null     Type
----------- -------- ------------------
AN_INTEGER           NUMBER
A_STRING             CHAR(3)
A_DATE               DATE

I'm guessing, however, you want some kind of generic way of determining this at runtime. This method would not be very useful since it involves DDL. In which case DBMS_SQL may help you:

From the DBMS_SQL Doc:

DECLARE
  c           NUMBER;
  d           NUMBER;
  col_cnt     INTEGER;
  f           BOOLEAN;
  rec_tab     DBMS_SQL.DESC_TAB;
  col_num    NUMBER;
  PROCEDURE print_rec(rec in DBMS_SQL.DESC_REC) IS
  BEGIN
    DBMS_OUTPUT.NEW_LINE;
    DBMS_OUTPUT.PUT_LINE('col_type            =    '
                         || rec.col_type);
    DBMS_OUTPUT.PUT_LINE('col_maxlen          =    '
                         || rec.col_max_len);
    DBMS_OUTPUT.PUT_LINE('col_name            =    '
                         || rec.col_name);
    DBMS_OUTPUT.PUT_LINE('col_name_len        =    '
                         || rec.col_name_len);
    DBMS_OUTPUT.PUT_LINE('col_schema_name     =    '
                         || rec.col_schema_name);
    DBMS_OUTPUT.PUT_LINE('col_schema_name_len =    '
                         || rec.col_schema_name_len);
    DBMS_OUTPUT.PUT_LINE('col_precision       =    '
                         || rec.col_precision);
    DBMS_OUTPUT.PUT_LINE('col_scale           =    '
                         || rec.col_scale);
    DBMS_OUTPUT.PUT('col_null_ok         =    ');
    IF (rec.col_null_ok) THEN
      DBMS_OUTPUT.PUT_LINE('true');
    ELSE
      DBMS_OUTPUT.PUT_LINE('false');
    END IF;
  END;
BEGIN
  c := DBMS_SQL.OPEN_CURSOR;

  DBMS_SQL.PARSE(c, 'SELECT * FROM scott.bonus', DBMS_SQL.NATIVE);

  d := DBMS_SQL.EXECUTE(c);

  DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);

/*
 * Following loop could simply be for j in 1..col_cnt loop.
 * Here we are simply illustrating some of the PL/SQL table
 * features.
 */
  col_num := rec_tab.first;
  IF (col_num IS NOT NULL) THEN
    LOOP
      print_rec(rec_tab(col_num));
      col_num := rec_tab.next(col_num);
      EXIT WHEN (col_num IS NULL);
    END LOOP;
  END IF;

  DBMS_SQL.CLOSE_CURSOR(c);
END;
/
Jeffrey Kemp
Actually, I just wanted to confirm the implicit type conversion rules in a query. However, this approach will most likely be useful as my database design (and eventually database) matures.
Steven