如何从PL / SQL过程执行'describe table_name'命令?

时间:2016-04-18 10:40:46

标签: oracle plsql dynamic-sql

我在Oracle中有以下过程:

create procedure clone_tables
(current_table_name varchar2, cloned_table_name varchar2);

我必须克隆一张桌子,但我只收到它的名字。 在这种情况下,我认为我必须得到它的结构,所以describe table_name命令就足够了。 现在,execute immediatedbms_sql.execute()仅使用SQL语句。

我还有其他办法吗?

3 个答案:

答案 0 :(得分:2)

如果您需要构建表的克隆,可以使用:

create or replace procedure clone_tables (current_table_name varchar2,
                                          cloned_table_name varchar2
                                          ) as
begin
    execute immediate
      'create table ' || cloned_table_name ||
      ' as select * from ' || current_table_name
      ' where 1 = 0 ' ;  /* to avoid copying records */
end;
/

这将构建一个与起始列完全相同的表,而不需要扫描所有列。这样你就不会复制起始表的记录了;如果要复制记录,只需删除WHERE条件即可。 正如Alex Poole正确地说的那样,这只会创建克隆表,但不会在克隆表上创建任何触发器,索引,外键......。

答案 1 :(得分:1)

查询USER_TAB_COLUMNS以获取列及其类型的列表。

答案 2 :(得分:0)

由于您提到DESCRIBE(...),您必须使用SQL * Plus - 或者理解SQL * Plus命令的图形程序,如Toad或SQL Developer。遗憾的是,您无法在SQL或PL / SQL中执行DESCRIBE命令,因为DESCRIBE是SQL * Plus命令,它不是SQL或PL / SQL命令。

如果您确实使用SQL Developer或Toad,它们有一个功能,您可以在其中显示一个表,它为您提供SQL(不是PL / SQL - 不需要,只需要简单且非常快速的SQL)重新创建表,INCLUDING约束和注释。下面我将在SQL Developer上的练习SQL表中重现使用此功能的输出。这只会创建表结构,而不是数据;你仍然需要复制数据,例如用

INSERT INTO (new_table) (SELECT * FROM old_table)

优于Alexsej解决方案的优势在于数据类型将被精确复制;在Aleksej的解决方案中,列不一定完全相同 - [例如,在旧表中,您可能有一个VARCHAR2(300)列;宽度300不会使用他的方法复制,而是使用表格中存在的实际数据的宽度。] 编辑正如Alex Poole在评论中指出的那样,我在这里(方括号中)说的是INCORRECT,用Aleksej的解决方案克隆表格会保留列宽等等。(另外,他的方法不会复制约束,如NOT NULL和UNIQUE。)

我推荐的方法仍然不会重新创建触发器,但它会重新创建约束和索引。

以下是SQL Developer可以为您做的一个示例,您可以选择NO EFFORT:

  CREATE TABLE "INTRO"."COURSES" 
   (    "CODE" VARCHAR2(6 BYTE) NOT NULL ENABLE, 
    "DESCRIPTION" VARCHAR2(30 BYTE) NOT NULL ENABLE, 
    "CATEGORY" CHAR(3 BYTE) NOT NULL ENABLE, 
    "DURATION" NUMBER(2,0) NOT NULL ENABLE, 
     CONSTRAINT "COURSES_PK" PRIMARY KEY ("CODE")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM"  ENABLE, 
     CONSTRAINT "COURSES_CAT_CHK" CHECK (CATEGORY in ('GEN','BLD','DSG')) ENABLE
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;

   COMMENT ON COLUMN "INTRO"."COURSES"."CODE" IS 'Unique course code';
   COMMENT ON COLUMN "INTRO"."COURSES"."DESCRIPTION" IS 'Course description (title)';
   COMMENT ON COLUMN "INTRO"."COURSES"."CATEGORY" IS 'Course category (GEN, BLD or DSG)';
   COMMENT ON COLUMN "INTRO"."COURSES"."DURATION" IS 'Course duration (in days)';
祝你好运!