如何从 PL/SQL 过程执行 'describe table_name' 命令?
How can I execute 'describe table_name' command from a PL/SQL procedure?
我在 Oracle 中有以下过程:
create procedure clone_tables
(current_table_name varchar2, cloned_table_name varchar2);
我必须克隆一个 table,但我只收到它的名称。
在这种情况下,我想我必须得到它的结构,所以 describe table_name
命令就足够了。
现在,execute immediate
或 dbms_sql.execute()
仅使用 SQL 语句。
还有其他方法吗?
查询 USER_TAB_COLUMNS 以获取列及其类型的列表。
如果您需要构建 table 的克隆,您可以使用:
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;
/
这将构建一个 table,其中的列与起始列完全相同,无需扫描所有列。这样就不会复制起始table的记录;如果要复制记录,只需删除 WHERE
条件即可。
正如 Alex Poole 所说的那样,这只会创建克隆 table,但不会创建任何触发器、索引、外键……存在于克隆 table.
上
既然你提到了 DESCRIBE (...),你必须使用 SQL*Plus - 或理解 SQL*Plus 命令的图形程序,如 Toad 或 SQL开发商。不幸的是,您不能在 SQL 或 PL/SQL 中执行 DESCRIBE 命令,因为 DESCRIBE 是 SQL*Plus 命令,它不是 SQL 或 [=28] =]命令。
如果您确实使用 SQL Developer 或 Toad,它们有一个功能,您可以在其中调出 table,它会给您 SQL(不是 PL/SQL -这不是必需的,简单且非常快速 SQL 就是所需要的)重新创建 tables,包括约束和注释。下面我将在 SQL Developer 中重现使用此功能的输出,实践 SQL table。这只会创建 table 结构,而不是它的数据;您仍然需要复制数据,例如
INSERT INTO (new_table) (SELECT * FROM old_table)
与 Alexsej 解决方案相比的优势在于数据类型将被准确复制;在 Aleksej 的解决方案中,列不一定完全相同 - [例如,在旧的 table 中,您可能有一个 VARCHAR2(300) 列;宽度 300 不会用他的方法复制,而是使用 table 中存在的实际数据的宽度。] 编辑:正如 Alex Poole 在评论中指出的那样,我在这里(在方括号中)所说的是不正确的,使用 Aleksej 的解决方案克隆 table 将保留列宽等。(此外,他的方法将不要复制约束,比如 NOT NULL 和 UNIQUE。)
我推荐的方法仍然不会重新创建触发器,但会重新创建约束和索引。
以下是 SQL 开发人员可以为您做的事情的示例,您无需付出任何努力:
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)';
祝你好运!
我在 Oracle 中有以下过程:
create procedure clone_tables
(current_table_name varchar2, cloned_table_name varchar2);
我必须克隆一个 table,但我只收到它的名称。
在这种情况下,我想我必须得到它的结构,所以 describe table_name
命令就足够了。
现在,execute immediate
或 dbms_sql.execute()
仅使用 SQL 语句。
还有其他方法吗?
查询 USER_TAB_COLUMNS 以获取列及其类型的列表。
如果您需要构建 table 的克隆,您可以使用:
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;
/
这将构建一个 table,其中的列与起始列完全相同,无需扫描所有列。这样就不会复制起始table的记录;如果要复制记录,只需删除 WHERE
条件即可。
正如 Alex Poole 所说的那样,这只会创建克隆 table,但不会创建任何触发器、索引、外键……存在于克隆 table.
既然你提到了 DESCRIBE (...),你必须使用 SQL*Plus - 或理解 SQL*Plus 命令的图形程序,如 Toad 或 SQL开发商。不幸的是,您不能在 SQL 或 PL/SQL 中执行 DESCRIBE 命令,因为 DESCRIBE 是 SQL*Plus 命令,它不是 SQL 或 [=28] =]命令。
如果您确实使用 SQL Developer 或 Toad,它们有一个功能,您可以在其中调出 table,它会给您 SQL(不是 PL/SQL -这不是必需的,简单且非常快速 SQL 就是所需要的)重新创建 tables,包括约束和注释。下面我将在 SQL Developer 中重现使用此功能的输出,实践 SQL table。这只会创建 table 结构,而不是它的数据;您仍然需要复制数据,例如
INSERT INTO (new_table) (SELECT * FROM old_table)
与 Alexsej 解决方案相比的优势在于数据类型将被准确复制;在 Aleksej 的解决方案中,列不一定完全相同 - [例如,在旧的 table 中,您可能有一个 VARCHAR2(300) 列;宽度 300 不会用他的方法复制,而是使用 table 中存在的实际数据的宽度。] 编辑:正如 Alex Poole 在评论中指出的那样,我在这里(在方括号中)所说的是不正确的,使用 Aleksej 的解决方案克隆 table 将保留列宽等。(此外,他的方法将不要复制约束,比如 NOT NULL 和 UNIQUE。)
我推荐的方法仍然不会重新创建触发器,但会重新创建约束和索引。
以下是 SQL 开发人员可以为您做的事情的示例,您无需付出任何努力:
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)';
祝你好运!