source

낮은 권한을 가진 PL-SQL을 사용하는 Oracle에서 열 데이터 유형을 가져오려면 어떻게 해야 합니까?

ittop 2023. 2. 26. 10:29
반응형

낮은 권한을 가진 PL-SQL을 사용하는 Oracle에서 열 데이터 유형을 가져오려면 어떻게 해야 합니까?

Oracle 데이터베이스의 일부 테이블에 대한 "읽기 전용" 액세스 권한이 있습니다.일부 열에 대한 스키마 정보를 가져와야 합니다.MS SQL과 비슷한 것을 사용하고 싶습니다.sp_help.

다음 쿼리에 관심 있는 테이블이 표시됩니다.

SELECT * FROM ALL_TABLES

이 쿼리를 실행하면 Oracle에서 "스키마에서 테이블을 찾을 수 없습니다"라는 메시지가 표시되며 매개 변수가 정확합니다.

SELECT 
DBMS_METADATA.GET_DDL('TABLE', 'ITEM_COMMIT_AGG', 'INTAMPS') AS DDL
FROM DUAL;

Oracle 유니버설 번역기 9000을 사용해 본 결과 권한이 없기 때문에 이 기능이 작동하지 않는 것으로 나타났습니다.제약조건에 따라 PL-SQL 문을 사용하여 읽기 액세스 권한이 있는 테이블의 데이터 유형 및 데이터 길이를 가져오려면 어떻게 해야 합니까?

ALL_TAB_COLUMNSPL/SQL에서 쿼리 가능해야 합니다.DESC는 SQL*Plus 명령어입니다.

SQL> desc all_tab_columns;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OWNER                                     NOT NULL VARCHAR2(30)
 TABLE_NAME                                NOT NULL VARCHAR2(30)
 COLUMN_NAME                               NOT NULL VARCHAR2(30)
 DATA_TYPE                                          VARCHAR2(106)
 DATA_TYPE_MOD                                      VARCHAR2(3)
 DATA_TYPE_OWNER                                    VARCHAR2(30)
 DATA_LENGTH                               NOT NULL NUMBER
 DATA_PRECISION                                     NUMBER
 DATA_SCALE                                         NUMBER
 NULLABLE                                           VARCHAR2(1)
 COLUMN_ID                                          NUMBER
 DEFAULT_LENGTH                                     NUMBER
 DATA_DEFAULT                                       LONG
 NUM_DISTINCT                                       NUMBER
 LOW_VALUE                                          RAW(32)
 HIGH_VALUE                                         RAW(32)
 DENSITY                                            NUMBER
 NUM_NULLS                                          NUMBER
 NUM_BUCKETS                                        NUMBER
 LAST_ANALYZED                                      DATE
 SAMPLE_SIZE                                        NUMBER
 CHARACTER_SET_NAME                                 VARCHAR2(44)
 CHAR_COL_DECL_LENGTH                               NUMBER
 GLOBAL_STATS                                       VARCHAR2(3)
 USER_STATS                                         VARCHAR2(3)
 AVG_COL_LEN                                        NUMBER
 CHAR_LENGTH                                        NUMBER
 CHAR_USED                                          VARCHAR2(1)
 V80_FMT_IMAGE                                      VARCHAR2(3)
 DATA_UPGRADED                                      VARCHAR2(3)
 HISTOGRAM                                          VARCHAR2(15)

를 사용할 수 있습니다.desc명령어를 입력합니다.

desc MY_TABLE

그러면 열 이름, null이 유효한지 여부 및 데이터 유형(및 해당되는 경우 길이)이 표시됩니다.

이 경우에 대해 제가 찾은 최고의 해결책은

select column_name, data_type||
case
when data_precision is not null and nvl(data_scale,0)>0 then '('||data_precision||','||data_scale||')'
when data_precision is not null and nvl(data_scale,0)=0 then '('||data_precision||')'
when data_precision is null and data_scale is not null then '(*,'||data_scale||')'
when char_length>0 then '('||char_length|| case char_used 
                                                         when 'B' then ' Byte'
                                                         when 'C' then ' Char'
                                                         else null 
                                           end||')'
end||decode(nullable, 'N', ' NOT NULL')
from user_tab_columns
where table_name = 'TABLE_NAME'
and column_name = 'COLUMN_NAME';

@Aaron Stainback, 수정 감사합니다!

주의: 다른 SCHEMA에 있는 테이블에 대해 이 정보를 가져오려면 all_tab_columns 뷰를 사용합니다.이 문제는 어플리케이션이 보안을 위해 다른 SCHEMA를 사용하기 때문입니다.

다음을 사용합니다.

EG:

SELECT
    data_length 
FROM
    all_tab_columns 
WHERE
    upper(table_name) = 'MY_TABLE_NAME' AND upper(column_name) = 'MY_COL_NAME'
select t.data_type 
  from user_tab_columns t 
 where t.TABLE_NAME = 'xxx' 
   and t.COLUMN_NAME='aaa'

Oracle 11.2: 테이블에 있는 전체 데이터 유형 목록을 가져옵니다.

create table SOMETABLE (foo integer, bar varchar(300));
select data_type || '(' || data_length || ')' thetype
from user_tab_columns where TABLE_NAME = 'SOMETABLE';

인쇄:

NUMBER(22)
VARCHAR(300)

스크린샷:

문서: https://docs.oracle.com/cd/B19306_01/server.102/b14237/statviews_4462.htm#REFRN26277

select column_name, data_type || '(' || data_length || ')' as datatype
from all_tab_columns 
where TABLE_NAME = upper('myTableName')

빠르고 더러운 방법(예를 들어 데이터가 오라클에 저장되는 방법을 확인할 수 있음)

SQL> select dump(dummy) dump_dummy, dummy
     , dump(10) dump_ten
from dual

DUMP_DUMMY       DUMMY DUMP_TEN            
---------------- ----- --------------------
Typ=1 Len=1: 88  X     Typ=2 Len=2: 193,11 
1 row selected.

는 테이블의 sys.dummy 컬럼이 type=1(varchar2)인 반면 10은 Type=2(숫자)인 것을 나타냅니다.

이거 드셔보세요.

SELECT *
  FROM (SELECT column_name,
               data_type,
               data_type
               || CASE
                     WHEN data_precision IS NOT NULL
                          AND NVL (data_scale, 0) > 0
                     THEN
                        '(' || data_precision || ',' || data_scale || ')'
                     WHEN data_precision IS NOT NULL
                          AND NVL (data_scale, 0) = 0
                     THEN
                        '(' || data_precision || ')'
                     WHEN data_precision IS NULL AND data_scale IS NOT NULL
                     THEN
                        '(*,' || data_scale || ')'
                     WHEN char_length > 0
                     THEN
                        '(' || char_length
                        || CASE char_used
                              WHEN 'B' THEN ' Byte'
                              WHEN 'C' THEN ' Char'
                              ELSE NULL
                           END
                        || ')'
                  END
               || DECODE (nullable, 'N', ' NOT NULL')
                  DataTypeWithLength
          FROM user_tab_columns
         WHERE table_name = 'CONTRACT')
 WHERE DataTypeWithLength = 'CHAR(1 Byte)';

사용할 수 있는 내부 표현 크기를 바이트 단위로 표시하려면:

REGEXP_SUBSTR(DUMP(your_column_name), 'Len=(\d+)\:', 1, 1, 'c', 1 ) 
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;

-- YOUR SELECT HERE
  DBMS_SQL.PARSE(c, '

SELECT *
FROM table1 a
     bable2 b
     table3 c
where a.id = b.id
  and b.id2 = c.id

  ', DBMS_SQL.NATIVE);

  d := DBMS_SQL.EXECUTE(c);

  DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);

  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;
/

언급URL : https://stackoverflow.com/questions/2339053/how-do-i-get-column-datatype-in-oracle-with-pl-sql-with-low-privileges

반응형