一个查询Oracle数据字典的程序

A program to query Oracle Data Dictionary

我正在解决一些 oracle 练习题以准备面试。我应该编写一个脚本来提供所有信息,并复制 Oracle 的 SQL*Plus describe 命令的格式,并且输出应该在行上添加注释。

输入:所有者和table姓名。
输出:Name、Null?、Type、Comments 列。

这个问题让我很困惑。我可以有效地查询数据字典,但我真的不知道我到底应该做什么。

我想出了这个,但我留下了评论部分。

select column_name AS "Name",
       (case when nullable = 'N'
             then 'NOT NULL'
             else null
         end) AS "Null?",
       (case when data_type = 'DATE'
             then data_type
             when data_type = 'NUMBER' and data_scale > 0
             then data_type || '(' || data_precision || ',' || data_scale || ')'
             when data_type = 'NUMBER' and data_scale = 0
             then data_type || '(' || data_precision || ')'
             when data_type = 'VARCHAR2'
             then data_type || '(' || data_length || ')'
        end) AS "Type"
  from user_tab_columns
 where table_name = UPPER('&table_name')
 order by column_id;

您可以使用单个 select 的 USER_TAB_COLUMNS 字典视图来实现它。如果您希望它为其创建 PL/SQL script 然后在 for loop 中使用此查询并使用具有所需格式的 DBMS_OUTPUT 将其显示到输出中,如下所示:

SQL> DESC EMPLOYEES;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 FIRSTNAME                                          VARCHAR2(100)
 CITY                                               VARCHAR2(100)

SQL> column "Name" format a41
SQL> column "Null?" format a8
SQL> column "Type" format a28
SQL> SELECT
  2      COLUMN_NAME   AS "Name",
  3      DECODE(NULLABLE,'N','NOT NULL')      AS "Null?",
  4      DATA_TYPE
  5      || '('
  6      || DATA_LENGTH
  7      || ')' AS "Type"
  8  FROM
  9      USER_TAB_COLUMNS
 10  WHERE
 11      TABLE_NAME = 'EMPLOYEES';

Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
ID                                        NOT NULL NUMBER(22)
FIRSTNAME                                          VARCHAR2(100)
CITY                                               VARCHAR2(100)

SQL>

--更新--

DESCRIBEDESC 命令不提供 oracle document 中提到的 comment column 以及根据以下演示。

The description for tables, views, types and synonyms contains the following information:

each column's name

whether or not null values are allowed (NULL or NOT NULL) for each column

datatype of columns, for example, CHAR, DATE, LONG, LONGRAW, NUMBER, RAW, ROWID, VARCHAR2 (VARCHAR), or XMLType

precision of columns (and scale, if any, for a numeric column)

SQL> comment on column EMPLOYEES.ID is 'unique id';

Comment created.

SQL> DESC EMPLOYEES;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 FIRSTNAME                                          VARCHAR2(100)
 CITY                                               VARCHAR2(100)

SQL> DESCRIBE EMPLOYEES;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 FIRSTNAME                                          VARCHAR2(100)
 CITY                                               VARCHAR2(100)

SQL>

如果您确实希望 comment 作为结果的一部分,请使用以下查询:

SQL> SELECT
  2      UT.COLUMN_NAME   AS "Name",
  3      DECODE(UT.NULLABLE, 'N', 'NOT NULL') AS "Null?",
  4      UT.DATA_TYPE
  5      || '('
  6      || UT.DATA_LENGTH
  7      || ')' AS "Type",
  8      UC.COMMENTS
  9  FROM
 10      USER_TAB_COLUMNS UT
 11      JOIN USER_COL_COMMENTS UC ON ( UT.TABLE_NAME = UC.TABLE_NAME
 12                                     AND UT.COLUMN_NAME = UC.COLUMN_NAME )
 13  WHERE
 14      UT.TABLE_NAME = 'EMPLOYEES';

Name                      Null?    Type                 COMMENTS
------------------------- -------- -------------------- --------------------
ID                        NOT NULL NUMBER(22)           unique id
FIRSTNAME                          VARCHAR2(100)
CITY                               VARCHAR2(100)

SQL>

干杯!!

只是扩展@Tejash 的答案。如果你想包含评论列,你可以在上面的查询中加入 USER_COL_COLUMNS 视图 -

SELECT
        UTC.COLUMN_NAME   AS "Name",
        DECODE(NULLABLE,'N','NOT NULL')      AS "Null?",
        DATA_TYPE
        || '('
        || DATA_LENGTH
        || ')' AS "Type",
        DATA_DEFAULT "Default",
        UCC.COMMENTS "EMPLOYEES"
   FROM
        USER_TAB_COLUMNS UTC
   JOIN USER_COL_COMMENTS UCC ON UTC.COLUMN_NAME = UCC.COLUMN_NAME
                               AND UTC.TABLE_NAME = UCC.TABLE_NAME
   WHERE
       UTC.TABLE_NAME = 'T1';

我也添加了默认列。 Here 是演示。

您的查询已扩展为包含评论。评论来自 ALL_TAB_COMMENTS 和 ALL_COL_COMMENTS 等观点。连接是 LEFT OUTER JOIN,因为并非所有列都有注释。

注意:您应该使用 ALL_% 视图,因为问题表明输入包括 owner,这强烈表明输入可能针对另一个模式,而不是您所连接的模式。 (可能应该是 DBA_% views 但 desc 不适用于我们没有权限的表。)

另外:您的查询只处理三种数据类型。说 CLOB 或 CHAR 是错误的。

select tc.column_name AS "Name",
       (case when tc.nullable = 'N'
             then 'NOT NULL'
             else null
         end) AS "Null?",
       (case when tc.data_type = 'NUMBER' and data_scale > 0
             then tc.data_type || '(' || data_precision || ',' || data_scale || ')'
             when tc.data_type = 'NUMBER' and data_scale = 0
             then tc.data_type || '(' || data_precision || ')'
             when tc.data_type in ('VARCHAR2', 'CHAR')
             then tc.data_type || '(' || data_length || ')'
             else tc.data_type
        end) AS "Type"
        , cc.comments
  from all_tab_columns tc
       left outer join all_col_columns cc
          on   cc.owner = tc.owner
          and  cc.table_name = tc.table_name
          and  cc.column_name = tc.column_name
 where tc.owner = UPPER('&owner')
 and   tc.table_name = UPPER('&table_name')
 order by tc.column_id;