Oracle: is it possible to create a copy of a IOT using CTAS without specifying columns?

别来无恙 提交于 2019-12-13 04:17:51

问题


I make use of the CTAS (Create Table As Select) syntax to create a copy of a table, in this way:

CREATE TABLE TABLE2 AS SELECT * FROM TABLE1;

So TABLE2 is a full copy of TABLE1, with all its columns.

I would like to make the same thing with the IOT tables.

But if I try to execute the following:

CREATE TABLE IOT_TABLE2 ORGANIZATION INDEX AS SELECT * FROM IOT_TABLE1;

I obtain:

ORA-25175: no PRIMARY KEY constraint found

There is some trick to do that, or is simply impossible to create a copy without specifying all columns?


回答1:


try as follows

CREATE TABLE IOT_TABLE2(id, col1, col2 .... , CONSTRAINT pk PRIMARY KEY (id)) 
ORGANIZATION INDEX AS SELECT * FROM IOT_TABLE1;

db<>fiddle here




回答2:


Thanks to @a_horse_with_no_name hint, I have found a proper solution.

Given this exemplification IOT DDL:

CREATE TABLE "IOT_TABLE1" 
   (    "COLUMN1" VARCHAR2(50) NOT NULL ENABLE, 
    "COLUMN2" VARCHAR2(50) NOT NULL ENABLE, 
    "COLUMN3" NUMBER(18,0) NOT NULL ENABLE, 
    "COLUMN4" BINARY_DOUBLE, 
     CONSTRAINT "TABLE1_IOT_PK" PRIMARY KEY ("COLUMN1", "COLUMN2", "COLUMN3") ENABLE
   ) ORGANIZATION INDEX NOCOMPRESS;

This is the SQL statement that can make a perfect copy of an IOT:

DECLARE 
    stmt VARCHAR2(4000);
BEGIN 
    DBMS_METADATA.set_transform_param(DBMS_METADATA.session_transform, 'SQLTERMINATOR', false);
    DBMS_METADATA.set_transform_param(DBMS_METADATA.session_transform, 'PRETTY', true);
    DBMS_METADATA.set_transform_param(DBMS_METADATA.session_transform, 'SEGMENT_ATTRIBUTES', false);
    DBMS_METADATA.set_transform_param(DBMS_METADATA.session_transform, 'STORAGE', false);
    SELECT TO_CHAR(DBMS_METADATA.get_ddl('TABLE','IOT_TABLE1')) INTO stmt FROM DUAL;
    stmt := REPLACE(stmt, 'TABLE1_IOT_PK', 'TABLE2_IOT_PK');
    stmt := REPLACE(stmt, 'TABLE1', 'TABLE2');
    stmt := regexp_replace(stmt, '^\s+(\()*\s*"(\w+).+$',chr(9)||'\1"\2",',1,0,'m');
    stmt := stmt || 'AS SELECT * FROM TABLE1';
    dbms_output.put_line(stmt);
    EXECUTE IMMEDIATE STMT;
END;

There are 3 replacements:

  1. The PK name
  2. The TABLE name
  3. The TYPE informations must be eliminated, otherwise it fails with ORA-01773

Here db<>fiddle



来源:https://stackoverflow.com/questions/57146248/oracle-is-it-possible-to-create-a-copy-of-a-iot-using-ctas-without-specifying-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!