在Oracle中描述查询结果的模式?

时间:2014-01-06 21:36:58

标签: sql oracle ddl describe

是否可以获得与查询的Oracle DESCRIBE命令类似的结果?例如。我在几个表之间有一个连接,它限制了返回的列,我想把它写到一个文件中。我后来想要将该值从文件恢复到另一个DBMS中的自己的基表。

我可以单独描述所有表并手动修剪列,但我希望像DESC (select a,b from t1 join t2) as q这样的东西可以工作,但事实并非如此。

如果我没有create view权限,那么创建一个视图是行不通的。有没有办法直接描述查询结果?

3 个答案:

答案 0 :(得分:5)

如果您的查询表示要从一个数据库中提取并加载到另一个数据库的一组数据,那么在源数据库中为该查询创建一个视图显然是非常明智的。获得该视图后,您可以describe查看或以其他方式从各种数据字典表中提取您要查找的信息。

我认为有充分的理由选择基于自定义文件的自定义解决方案,通过Oracle为处理数据复制提供的任何技术将数据从一个数据库复制到另一个数据库。物化视图,Streams,GoldenGate等通常都是比编写自己的更好的解决方案。

如果不允许在源数据库上创建对象,则不能使用SQL * Plus describe命令。您可以编写一个匿名PL / SQL块,该块使用dbms_sql包来解析和描述动态SQL语句。这比使用describe命令要复杂得多,你必须弄清楚如何格式化输出。我会以this describe_columns example为出发点。

答案 1 :(得分:4)

如果您打算重新使用该查询,则可以为其创建视图 您可以使用与表相同的方式对数据库视图进行注释:

create view TEST_VIEW as select 'TEST' COL1 from dual;
comment on table TEST_VIEW IS 'TEST ONLY';

要查看对视图的评论,请执行以下命令:

select * from user_tab_comments where table_name='TEST_VIEW';

参考文献:

How to create a comment to an oracle database view

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:233014204543

注意:此URL指出SQLPLUS DESCRIBE命令仅应与“表,视图或同义词”或“函数或过程”一起使用。这意味着DESCRIBE的目标必须是现有的数据库对象。

http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12019.htm

作为SQLPLUS命令,DESCRIBE无法动态解析SQL语句。 DESCRIBE返回的所有信息都存储在数据字典中。

答案 2 :(得分:3)

我很晚才回答,但无论如何我会为后代添加这个。

在Oracle中,您可以使用DBMS_SQL包。

用法:

  1. 将您的SQL语句转换为单行(用空格替换换行符)
  2. 将单引号替换为两个单引号
  3. 将结果值放入STMT(在下面的脚本中)。
  4. 运行脚本。
  5. SET SERVEROUTPUT ON; DECLARE STMT CLOB; CUR NUMBER; COLCNT NUMBER; IDX NUMBER; COLDESC DBMS_SQL.DESC_TAB2; BEGIN CUR := DBMS_SQL.OPEN_CURSOR; STMT := ''; SYS.DBMS_SQL.PARSE(CUR, STMT, DBMS_SQL.NATIVE); DBMS_SQL.DESCRIBE_COLUMNS2(CUR, COLCNT, COLDESC); DBMS_OUTPUT.PUT_LINE('Statement: ' || STMT); FOR IDX IN 1 .. COLCNT LOOP CASE COLDESC(IDX).col_type WHEN 2 THEN DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': NUMBER'); WHEN 12 THEN DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': DATE'); WHEN 180 THEN DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': TIMESTAMP'); WHEN 1 THEN DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': VARCHAR'); WHEN 9 THEN DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': VARCHAR2'); -- Insert more cases if you need them ELSE DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': OTHERS (' || TO_CHAR(COLDESC(IDX).col_type) || ')'); END CASE; END LOOP; SYS.DBMS_SQL.CLOSE_CURSOR(CUR); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLERRM(SQLCODE()) || ': ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE); SYS.DBMS_SQL.CLOSE_CURSOR(CUR); END;

    我没有在下面的脚本中涵盖所有可能的数据类型,如果需要,可以添加更多案例。您可以使用此SQL查找有关数据类型值的信息: select text from all_source where owner = 'SYS' and name = 'DBMS_TYPES' and type = 'PACKAGE'

    Toad World在这里列出了可能的数据类型: http://www.toadworld.com/platforms/oracle/w/wiki/3328.dbms-sql-describe-columns

    除了在这个帖子中,我在Oracle上找不到相同的列表: https://community.oracle.com/thread/914475

    实施例: -- snip STMT := 'SELECT * FROM SYS.ALL_TAB_COLS'; -- snip 会给你: anonymous block completed Statement: SELECT * FROM SYS.ALL_TAB_COLS #1: VARCHAR2 (1) #2: VARCHAR2 (1) #3: VARCHAR2 (1) #4: VARCHAR2 (1) #5: VARCHAR2 (1) #6: VARCHAR2 (1) #7: NUMBER #8: NUMBER #9: NUMBER #10: VARCHAR2 (1) #11: NUMBER #12: NUMBER #13: VARCHAR2 (8) #14: NUMBER #15: VARCHAR2 (23) #16: VARCHAR2 (23) #17: NUMBER #18: NUMBER #19: NUMBER #20: DATE #21: NUMBER #22: VARCHAR2 (1) #23: NUMBER #24: VARCHAR2 (1) #25: VARCHAR2 (1) #26: NUMBER #27: NUMBER #28: VARCHAR2 (1) #29: VARCHAR2 (1) #30: VARCHAR2 (1) #31: VARCHAR2 (1) #32: VARCHAR2 (1) #33: NUMBER #34: NUMBER #35: VARCHAR2 (1) #36: VARCHAR2 (1)