Indexing a ranged partition Oracle - oracle

I want to index a partition of my table, I'm not sure how to do it and I don't have access to my database atm.
The database is Oracle 11.
Would my code work?
CREATE TABLE MARKET.PARTTABLE
(
EXTRACT_DATE DATE NOT NULL,
LOAD_ID NUMBER(10) NOT NULL,
LOAD_DATE DATE NOT NULL,
NAME VARCHAR2(200 BYTE) NOT NULL
)
PARTITION BY RANGE (EXTRACT_DATE)
(
PARTITION PDEFAULT VALUES LESS THAN (MAXVALUE)
NOLOGGING
NOCOMPRESS
TABLESPACE MARKET_DAT
PCTFREE 0
INITRANS 1
MAXTRANS 255
STORAGE (
MAXSIZE UNLIMITED
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
CREATE INDEX NAME_PARTTABLE ON PARTTABLE(NAME)
)
NOCACHE
NOPARALLEL
MONITORING;
When I run this I get the following error:
ORA-14020: this physical attribute may not be specified for a table
partition
This indicates that I have a formatting issue, but I actually don't find any helpful documentation to index partition (or maybe I'm just too stupid to understand them).
EDIT:
I tried this:
CREATE TABLE MARKET.PARTTABLE
(
EXTRACT_DATE DATE NOT NULL,
LOAD_ID NUMBER(10) NOT NULL,
LOAD_DATE DATE NOT NULL,
NAME VARCHAR2(200 BYTE) NOT NULL
)
PARTITION BY RANGE (EXTRACT_DATE)
(
PARTITION PDEFAULT VALUES LESS THAN (MAXVALUE)
NOLOGGING
NOCOMPRESS
TABLESPACE MARKET_DAT
PCTFREE 0
INITRANS 1
MAXTRANS 255
STORAGE (
MAXSIZE UNLIMITED
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
)
NOCACHE
NOPARALLEL
MONITORING;
CREATE INDEX NAME_PARTTABLE ON PARTTABLE(NAME)
It worked, but I'm not sure if the index is now on the partition or if it is on the whole table. Could someone help me out?

Your second statement did not in fact create an INDEX on the partition.
Partitioned indexes should either be defined as LOCAL or GLOBAL.
Since what you are trying to create is a Non-Prefixed index( The leftmost column(s) of the index is not the partition key), better option is to go with a LOCAL INDEX
CREATE INDEX NAME_PARTTABLE ON PARTTABLE(NAME) LOCAL;
..but I'm not sure if the index is now on the partition or if
it is on the whole table.
You may query the data dictionary view ALL_PART_INDEXES or USER_PART_INDEXES to check for your index name. Normal non-partitioned indexes aren't shown from these views.
select * from USER_PART_INDEXES where index_name='NAME_PARTTABLE';
Partitioned Tables And Indexes

Related

Storage Clause is getting skipped for LOB segment in Oracle 12c

Hi have created table which consist clob datatype :
CREATE TABLE MQ_GET_CLOB
(
SEQ_NO NUMBER NOT NULL,
MESSAGE_TEXT CLOB,
MESSAGE_LENGTH NUMBER NOT NULL,
STATUS VARCHAR2(15 BYTE)
)
TABLESPACE DATA_L1
LOB (MESSAGE_TEXT) STORE AS
(TABLESPACE DATA_L1
STORAGE (INITIAL 6144)
CHUNK 4000
NOCACHE LOGGING);
After creating table when I looked into Metadata , I found that LOB storage clause is getting skipped.
CREATE TABLE MQ_GET_CLOB
(
SEQ_NO NUMBER NOT NULL,
MESSAGE_TEXT CLOB,
MESSAGE_LENGTH NUMBER NOT NULL,
STATUS VARCHAR2(15 BYTE)
)
TABLESPACE DATA_L1
PCTUSED 40
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
Which leads to
ORA-01658: unable to create INITIAL extent for segment in tablespace
SYSAUX
I am not sure why table is using SYSAUX tablespace.
Whether anyone have faced same issue before ? This there something I have missed ?
Thanks.

Conflict creating table with Index and Primary Key

I'm a veteran SQL Server dev, recently moved to a project requiring Oracle and I'm confused by the error [ORA-02260: table can have only one primary key] I'm getting on Oracle 11.
I'm attempting to create a reference table, with an index and a primary key.
However, getting errors that my column Partner_ID is already declared. I know I'm missing something simple, but the docs and other sources I've viewed here have not given me a clue. Please help me understand what I'm doing wrong.
Thank you
ALTER TABLE REF_PARTNER
DROP PRIMARY KEY CASCADE;
DROP TABLE REF_PARTNER CASCADE CONSTRAINTS;
CREATE TABLE REF_PARTNER
(
PARTNER_ID NUMBER(10) PRIMARY KEY NOT NULL,
GLOBAL_APPID VARCHAR2(256 BYTE) NOT NULL,
FRIENDLY_NAME VARCHAR2(256 BYTE) NOT NULL,
CREATE_DTS DATE,
MODIFIED_DTS DATE,
LAST_MODIFIED_USER VARCHAR2(40 BYTE)
)
TABLESPACE DATA_1
PCTUSED 0
PCTFREE 5
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 1M
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
MONITORING;
BEGIN
EXECUTE IMMEDIATE 'DROP SEQUENCE PARTNER_SEQ';
EXCEPTION WHEN OTHERS THEN NULL;
END;
CREATE SEQUENCE PARTNER_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 1 NOMAXVALUE NOCYCLE CACHE 200;
--CREATE UNIQUE INDEX REF_PARTNER_IDX ON REF_PARTNER
--(PARTNER_ID)
--LOGGING
--TABLESPACE INDEX_1
--PCTFREE 10
--INITRANS 2
--MAXTRANS 255
--STORAGE (
-- INITIAL 64K
-- NEXT 64K
-- MAXSIZE UNLIMITED
-- MINEXTENTS 1
-- MAXEXTENTS UNLIMITED
-- PCTINCREASE 0
-- BUFFER_POOL DEFAULT
-- );
--ALTER TABLE REF_PARTNER ADD (
-- CONSTRAINT REF_PARTNER_PK
-- PRIMARY KEY
-- (PARTNER_ID)
-- USING INDEX REF_PARTNER_PK
-- ENABLE VALIDATE);
A assume the error you get is
ORA-01408: such column list already indexed.
This is because you create the table with partner_id as the primary key. This automatically creates a unique index on partner_id.
There is no need to create a unique key on partner_id after you declared it to be the primary key.

Toad for Oracle, Editing ID Column to be an auto-increment ID

I work with Toad for Oracle 12.1 for my database. I have a Table called TBLEMPLOYEE which already contain some data in it and having Column Name called ID whose data values are increasing from 1 to N.
ID Name Gender DateOfBirth Type
------------------------------------
1 Mark Male 10/10/1982 1
2 Mary Female 11/11/1981 2
3 Esther Female 12/12/1984 2
4 Matthew Male 9/9/1983 1
5 John Male 5/5/1985 1
6 Luke Male 6/6/1986 1
Now I want to change the Column ID such that it will have auto-incremented ID when I add a new data to the Table.
I know that in Toad we can do it when we create a New Table with that behavior. For instance, using Create Table and in the newly created Column, we could set Default / Virtual / Identity settings as Identity:
And Toad will show a UI with bunch of settings to do that:
And will be automatically translated to something like:
(START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 9999999999999999999999999999 CACHE 20 NOCYCLE ORDER NOKEEP)
In the Default / Virtual / Identity settings.
But I can't seem to do the same when I do Alter Table instead of Create Table.
Why is that so?
And since I already have some data in the TBLEMPLOYEE, I want to avoid creating a new table and re-inserting the data if possible.
How can I do that?
This is the current SQL script (if this may help):
ALTER TABLE MYSCHEMA.TBLEMPLOYEE
DROP PRIMARY KEY CASCADE;
DROP TABLE MYSCHEMA.TBLEMPLOYEE CASCADE CONSTRAINTS;
CREATE TABLE MYSCHEMA.TBLEMPLOYEE
(
ID NUMBER NOT NULL,
NAME VARCHAR2(80 BYTE) NOT NULL,
GENDER VARCHAR2(6 BYTE),
DATEOFBIRTH DATE,
EMPLOYEETYPE INTEGER NOT NULL,
)
TABLESPACE USERS
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
ALTER TABLE MYSCHEMA.TBLEMPLOYEE ADD (
PRIMARY KEY
(ID)
USING INDEX
TABLESPACE USERS
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
ENABLE VALIDATE);
First of all, your sequence should start with the max value + 1 from the table e.g.
(START WITH 7 INCREMENT BY 1 MINVALUE 1 MAXVALUE 9999999999999999999999999999 CACHE 20 NOCYCLE ORDER NOKEEP)
If you want to automatically populate the value for the Id and you're not running on Oracle 12c, I suggest you to use a trigger
drop sequence seq_mytest_id;
truncate table my_test_t;
drop table my_test_t;
create table my_test_t (id number, string varchar2(30));
-- prepopulate with fixed values for the id
insert into my_test_t(id, string) values (1,'test');
insert into my_test_t(id, string) values (2,'test');
insert into my_test_t(id, string) values (3,'test');
insert into my_test_t(id, string) values (4,'test');
insert into my_test_t(id, string) values (5,'test');
insert into my_test_t(id, string) values (6,'test');
commit;
--Now create the sequence and the trigger for automatically
--populating the ID column
create sequence seq_mytest_id start with 7 increment by 1 nocycle nocache;
create trigger t_mytest_bi before insert on my_test_t for each row
begin
select seq_mytest_id.nextval into :new.id from dual;
end;
/
-- Test the trigger
insert into my_test_t(string) values ('test');
insert into my_test_t(string) values ('test2');
commit;
select * from my_test_t;
If you're running on Oracle 12c you can define your column as an identity column
https://oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1
Hope it helps,
R

Migrating table with composite partition (Hash/Range) to different tablespace

Trying to move table tab from tablespace oldTs to newTs. There is a composite partition (Range/Hash) on tab. Hence, a direct "Alter-Table-Move-Tablespace" query won't work, need to migrate partition by partition. Below is the SQL of tab:
CREATE TABLE tab
(
col_1 char(6),
col_2 varchar2(4),
col_3 varchar2(5)
)
TABLESPACE oldTs PARTITION BY RANGE
(
"col_1"
)
SUBPARTITION BY HASH
(
"col_2"
)
SUBPARTITIONS 1
(
PARTITION "P201102" VALUES LESS THAN ('201103') PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 STORAGE( BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "oldTs" NOCOMPRESS NOLOGGING ( SUBPARTITION "SYS_SUBP5223" TABLESPACE "oldTs" NOCOMPRESS , SUBPARTITION "SYS_SUBP5224" TABLESPACE "oldTs" NOCOMPRESS ),
PARTITION "P201103" VALUES LESS THAN ('201104') PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 STORAGE( BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "oldTs" NOCOMPRESS NOLOGGING ( SUBPARTITION "SYS_SUBP5225" TABLESPACE "oldTs" NOCOMPRESS , SUBPARTITION "SYS_SUBP5226" TABLESPACE "oldTs" NOCOMPRESS )
);
There are several such monthly partitions, created a procedure which acquires all the partition names (such as P201102, P2001103) and generates an alter query for moving partitions.
For ex,
ALTER TABLE tab_name MOVE PARTITION P201102 TABLESPACE newTbs;
But, the query gives below error:
SQL Error: ORA-14257: cannot move partition other than a Range, List,
System, or Hash partition
Also, if you notice in P201102/P201103, each has two sub-partitions (SYS_SUBP5225 & SYS_SUBP5226 for P201103).
Require the correct syntax of alter statement for migrating partitions for the above scenario.
You can move subpartitions but not partitions which contains subpartitions. (Shortly, you can move segments.)
ALTER TABLE tab_name MOVE SUBPARTITION SYS_SUBP5225 TABLESPACE newTbs;
UPDATE: If you want to change where the new partitions are created then run the bellow ddl, which change an atribute of the table - where new partitions are created.
alter table tab_name modify default attributes tablespace newTbs;
UPDATE2: If you want to change where subpartitions are created for a partition, then run below which change an attribute of the partition - where new subpartitions are created:
alter table tab_name modify default attributes for partition P201102 tablespace newTbs;

How to import Oracle (C)LOB into another tablespace

I'm importing a database dump from one Oracle 10g installation into another. The source has a layout with several tablespaces. The target has one default tablespace for the user I'm importing the dump into.
Everything works fine, for ordinary tables. The tables are relocated from their original tablespace to the user's default. The problem I'm facing, several tables contain CLOBs with explicit storage directives. That is, they name their storage tablespace. The imp command seems to be unable to relocate these CLOBs to the user's default tablespace.
Is there any hidden command line option for the imp command to relocate the CLOB storage to the user's default tablespace or even one named tablespace?
The error message ORACLE 959 looks like this:
IMP-00017: Nachfolgende Anweisung war wegen Oracle-Fehler 959 erfolglos:
"CREATE TABLE "IF_MDE_DATA_OUT" ("OID" NUMBER(10, 0) NOT NULL ENABLE, "CLIEN"
"T_OID" NUMBER(10, 0) NOT NULL ENABLE, "TS_CREATE" TIMESTAMP (6) NOT NULL EN"
"ABLE, "TS_UPDATE" TIMESTAMP (6) NOT NULL ENABLE, "OP_CREATE" VARCHAR2(30) N"
"OT NULL ENABLE, "OP_UPDATE" VARCHAR2(30) NOT NULL ENABLE, "IDENTIFIER" VARC"
"HAR2(50), "TRANSFERTYPE" VARCHAR2(20) NOT NULL ENABLE, "STORE" NUMBER(10, 0"
"), "DATUM" DATE, "STATE" NUMBER(3, 0) NOT NULL ENABLE, "DATA_OLD" LONG RAW,"
" "SUPPLIER" NUMBER(10, 0), "BUYER" NUMBER(10, 0), "GOODS_OUT_IDS" VARCHAR2("
"4000), "CUSTOM_FIELD" VARCHAR2(50), "DATA_ARCHIVE" BLOB, "DATA" BLOB) PCTF"
"REE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1"
" FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "DATA32M" LOGGING NOCOMP"
"RESS LOB ("DATA_ARCHIVE") STORE AS (TABLESPACE "DATA32M" ENABLE STORAGE IN"
" ROW CHUNK 8192 PCTVERSION 10 NOCACHE LOGGING STORAGE(INITIAL 65536 FREELI"
"STS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)) LOB ("DATA") STORE AS (TABLE"
"SPACE "DATA32M" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10 NOCACHE LOGG"
"ING STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAUL"
"T))"
IMP-00003: ORACLE-Fehler 959 aufgetreten
ORA-00959: Tablespace 'DATA32M' nicht vorhanden
You could pre-create the table using the storage parameters you need, and set the import to ignore errors.
Like Karl, I recommend Datadump but use REMAP_TABLESPACE
If you are using Data Pump Dumps, you could try the remap_schema option to correct the tablespace.

Resources