oracle表达式计算长度

时间:2016-06-07 14:53:03

标签: sql oracle

当Oracle为查询创建视图时,它会计算视图的数据类型和数据长度,可以从ALL_TAB_COLUMNS.

查询

是否有一个函数可以访问这些计算值而无需创建视图?

CREATE OR REPLACE VIEW TEMP AS 
select 'This is a string. ' || 2020 || ' Another string' TEMP_COL from dual;

select * from ALL_TAB_COLUMNS
where TABLE_NAME = 'TEMP';

1 个答案:

答案 0 :(得分:1)

您可以使用DBMS_SQL来解析查询并获取列名,数据类型和长度/比例。

declare
  PROCEDURE temp (p_query IN VARCHAR2) IS
    col_cnt     INTEGER;
    rec_tab     dbms_sql.desc_tab2;
    v_tab       dbms_sql.varchar2s;
    v_cursor    NUMBER;
    v_line      varchar2(100);
    v_datatype  varchar2(100);
  BEGIN
    v_cursor := dbms_sql.open_cursor;
    dbms_sql.parse(v_cursor, p_query, 1);
    dbms_sql.describe_columns2(v_cursor, col_cnt, rec_tab);
    dbms_sql.close_cursor(v_cursor);
    FOR v_pos in 1..rec_tab.LAST LOOP
      v_datatype :=
            case rec_tab(v_pos).col_type
                  when 1   THEN  'VARCHAR2'
                  when 2   THEN  'NUMBER'
                  when 8   THEN  'LONG'
                  when 9   THEN  'VARCHAR'
                  when 12  THEN  'DATE'
                  when 23  THEN  'RAW'
                  when 24  THEN  'LONG RAW'
                  when 69  THEN  'ROWID'
                  when 96  THEN  'CHAR'
                  when 100 THEN  'BINARY_FLOAT'
                  when 101 THEN  'BINARY_DOUBLE'
                  when 112 THEN  'CLOB'
                  when 113 THEN  'BLOB'
                  when 114 THEN  'BFILE'
                  when 115 THEN  'CFILE'
                  when 178 THEN  'TIME'
                  when 179 THEN  'TIME WITH TIME ZONE'
                  when 180 THEN  'TIMESTAMP'
                  when 181 THEN  'TIMESTAMP WITH TIME ZONE'
                  when 231 THEN  'TIMESTAMP WITH LOCAL TIME ZONE'
                  when 182 THEN  'INTERVAL YEAR TO MONTH'
                  when 183 THEN  'INTERVAL DAY TO SECOND'
                  when 208 THEN  'UROWID'
                  else           'OTHER:'||rec_tab(v_pos).col_type
            end;
      if rec_tab(v_pos).col_precision > 0 and rec_tab(v_pos).col_scale > 0 then
        v_datatype := v_datatype||'('||rec_tab(v_pos).col_precision||','||rec_tab(v_pos).col_scale||')';
      elsif rec_tab(v_pos).col_precision > 0 and v_datatype != 'NUMBER' then
        v_datatype := v_datatype||'('||rec_tab(v_pos).col_precision||')';
      elsif rec_tab(v_pos).col_max_len > 0 and v_datatype != 'NUMBER' then
        v_datatype := v_datatype||'('||rec_tab(v_pos).col_max_len||')';
      else
        v_datatype := v_datatype;
      end if;
      v_line := rpad(rec_tab(v_pos).col_name,32)||
                rpad(v_datatype,32);
      dbms_output.put_line(v_line);
    END LOOP;
  END;
BEGIN
  temp( q'{select 'This is a string. ' || 2020 || ' Another string' TEMP_COL from dual }' );
END;
/