Why do I get an ORA-00922 when trying to create a partitioned table in Oracle? - oracle

I'm trying to create partitioned on oracle table but getting ORA-00922 error.
Error starting at line : 1 in command -
CREATE TABLE "RATE_REQUEST_BKP_PARIATIONED"
(
"RATE_REQUEST_ID" NUMBER(10,0),
"PRODUCT_CUSTOMER_ID" NUMBER(10,0),
"DESTINATION_ID" NUMBER(10,0),
"CREATED_DT" DATE,
"CREATED_BY" NUMBER(10,0),
"MODIFIED_DT" DATE,
"MODIFIED_BY" NUMBER(10,0),
"RATE_STATUS_ID" NUMBER(10,0)
)
PARTITION BY RANGE
(
CREATED_DT
)
INTERVAL
(
NUMTOYMINTERVAL(1, 'MONTH')
)
(
PARTITION p0 VALUES LESS THAN (TO_DATE('1-3-2017', 'DD-MM-YYYY')),
PARTITION p1 VALUES LESS THAN (TO_DATE('1-4-2017', 'DD-MM-YYYY')),
PARTITION p2 VALUES LESS THAN (TO_DATE('1-5-2017', 'DD-MM-YYYY'))
)
Error report -
SQL Error: ORA-00922: missing or invalid option
00922. 00000 - "missing or invalid option"
*Cause:
*Action:
Table "RATE_REQUEST_BKP_PARIATIONED" dropped.
Commit complete.
Please help me finding out the issue with query.

May this Help you
If an invalid option is specified while defining a storage clause or column, ORA-00922 will be thrown. ORA-00922 mentions that to specify that the column is not able to contain any NULL values, the valid option while specifying a column is NOT NULL, and solely constraints can follow the datatype.
Also notable to ORA-00922, which can also cause this error to be thrown, is that specifying a maximum length on LOG or DATE datatype.
Correcting ORA-00992 consists of correcting the syntax in your specifications, minding to take out the erroneous option or length specification from the storage of column specification
Answer got from this link
http://www.dba-oracle.com/t_ora_00922_missing_or_invalid_option.htm

Related

SQL Error: ORA-14006: invalid partition name

I am trying to partition an existing table in Oracle 12C R1 using below SQL statement.
ALTER TABLE TABLE_NAME MODIFY
PARTITION BY RANGE (DATE_COLUMN_NAME)
INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(
PARTITION part_01 VALUES LESS THAN (TO_DATE('01-SEP-2017', 'DD-MON-RRRR'))
) ONLINE;
Getting error:
Error report -
SQL Error: ORA-14006: invalid partition name
14006. 00000 - "invalid partition name"
*Cause: a partition name of the form <identifier> is
expected but not present.
*Action: enter an appropriate partition name.
Partition needs to be done on the basis of data datatype column with the interval of one month.
Min value of Date time column in the Table is 01-SEP-2017.
You can't partition an existing table like that. That statement is modifying the partition that hasn't been created yet. I don't know the automatic way to do this operation and I am not sure that you can do it.
Although I have done this thing many times but with manual steps. Do the following if you can't find an automated solution:
Create a partitioned table named table_name_part with your clauses and all your preferences.
Insert into this partitioned table all rows from original table. Pay attention to compression. If you have some compression on table (Basic or HCC) you have to use + APPEND hint.
Create on partitioned table your constrains and indexes from the original table.
Rename the tables and drop the original table. Do not drop it until you make some counts on them.
I saw that your table has the option to auto-create partition if it does not exists. (NUMTOYMINTERVAL(1,'MONTH')) So you have to create your table with first partition only. I assume that you have here a lot of read-only data, so you won't have any problem with consistency instead of last month. Probably there is some read-write data so there you have to be more careful with the moment when you want to insert data in new table and switch tables.
Hope to help you. As far as I know there might be a package named DBMS_REDEFINITION that can help you with an automated version of my steps. If you need more details or need some help on my method, please don't hesitate.
UPDATE:
From Oracle 12c R2 you can convert a table from an unpartitioned to a partitioned one with your method. Find a link below. Now this is a challenge for me and I am trying to convert, but I think there is no way to make this conversion online in 12c R1.
In previous releases you could partition a non-partitioned table using
EXCHANGE PARTITION or DBMS_REDEFINITION in an "almost online" manner,
but both methods require multiple steps. Oracle Database 12c Release 2
makes it easier than ever to convert a non-partitioned table to a
partitioned table, requiring only a single command and no downtime.
https://oracle-base.com/articles/12c/online-conversion-of-a-non-partitioned-table-to-a-partitioned-table-12cr2
Solution
I found a solution for you. Here you will have all of my steps that I run to convert table online. :)
1. Create regular table and populate it.
CREATE TABLE SCOTT.tab_unpartitioned
(
id NUMBER,
description VARCHAR2 ( 50 ),
created_date DATE
);
INSERT INTO tab_unpartitioned
SELECT LEVEL,
'Description for ' || LEVEL,
ADD_MONTHS ( TO_DATE ( '01-JAN-2017', 'DD-MON-YYYY' ),
-TRUNC ( DBMS_RANDOM.VALUE ( 1, 4 ) - 1 ) * 12 )
FROM DUAL
CONNECT BY LEVEL <= 10000;
COMMIT;
2. Create partitioned table with same structure.
--If you are on 11g create table with CREATE TABLE command but with different name. ex: tab_partitioned
CREATE TABLE SCOTT.tab_partitioned
(
id NUMBER,
description VARCHAR2 ( 50 ),
created_date DATE
)
PARTITION BY RANGE (created_date)
INTERVAL( NUMTOYMINTERVAL(1,'YEAR'))
(PARTITION part_2015 VALUES LESS THAN (TO_DATE ( '01-JAN-2016', 'DD-MON-YYYY' )),
PARTITION part_2016 VALUES LESS THAN (TO_DATE ( '01-JAN-2017', 'DD-MON-YYYY' )),
PARTITION part_2017 VALUES LESS THAN (TO_DATE ( '01-JAN-2018', 'DD-MON-YYYY' )));
--this is an alter command that works only in 12c.
ALTER TABLE tab_partitioned
MODIFY
PARTITION BY RANGE (created_date)
(PARTITION part_2015 VALUES LESS THAN (TO_DATE ( '01-JAN-2016', 'DD-MON-YYYY' )),
PARTITION part_2016 VALUES LESS THAN (TO_DATE ( '01-JAN-2017', 'DD-MON-YYYY' )),
PARTITION part_2017 VALUES LESS THAN (TO_DATE ( '01-JAN-2018', 'DD-MON-YYYY' )));
3. Check if the table can be converted. This procedure should run without any error.
Prerequisites: table should have an UNIQUE INDEX and a Primary Key constraint.
EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('SCOTT','TAB_UNPARTITIONED');
4. Run the following steps like I have done.
EXEC DBMS_REDEFINITION.START_REDEF_TABLE('SCOTT','TAB_UNPARTITIONED','TAB_PARTITIONED');
var num_errors varchar2(2000);
EXEC DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('SCOTT','TAB_UNPARTITIONED','TAB_PARTITIONED', 1,TRUE,TRUE,TRUE,FALSE,:NUM_ERRORS,FALSE);
SQL> PRINT NUM_ERRORS -- Should return 0
EXEC DBMS_REDEFINITION.SYNC_INTERIM_TABLE('SCOTT','TAB_UNPARTITIONED','TAB_PARTITIONED');
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('SCOTT','TAB_UNPARTITIONED','TAB_PARTITIONED');
At the end of the script you will see that the original table is partitioned.
Try Oracle Live SQL I used to use Oracle 11g EE and got the same error message. So I tried Oracle live SQL and it perfectly worked. It has very simple and easy to understand interface,
For example, I'm creating a sales table and inserting some dummy data and partition it using range partitioning method,
CREATE TABLE sales
(product VARCHAR(300),
country VARCHAR(100),
sales_year DATE);
INSERT INTO sales (product, country, sales_year )
VALUES ('Computer','Kazakhstan',TO_DATE('01/02/2018','DD/MM/YYYY'));
INSERT INTO sales (product, country, sales_year )
VALUES ('Mobile Phone','China',TO_DATE('23/12/2019','DD/MM/YYYY'));
INSERT INTO sales (product, country, sales_year )
VALUES ('Camara','USA',TO_DATE('20/11/2020','DD/MM/YYYY'));
INSERT INTO sales (product, country, sales_year )
VALUES ('Watch','Bangladesh',TO_DATE('19/03/2020','DD/MM/YYYY'));
INSERT INTO sales (product, country, sales_year )
VALUES ('Cake','Sri Lanka',TO_DATE('13/04/2021','DD/MM/YYYY'));
ALTER TABLE sales MODIFY
PARTITION BY RANGE(sales_year)
INTERVAL(INTERVAL '1' YEAR)
(
PARTITION sales_2018 VALUES LESS THAN(TO_DATE('01/01/2019','DD/MM/YYYY')),
PARTITION sales_2019 VALUES LESS THAN(TO_DATE('01/01/2020','DD/MM/YYYY')),
PARTITION sales_2020 VALUES LESS THAN(TO_DATE('01/01/2021','DD/MM/YYYY')),
PARTITION sales_2021 VALUES LESS THAN(TO_DATE('01/01/2022','DD/MM/YYYY'))
)ONLINE;
Finally, I can write SELECT query for partitions to confirm that the partitions are created successfully.
SELECT *
FROM sales PARTITION (sales_2020);
And it gives the expected output,

Oracle 11g _ ORA-00904 error message with Insert statement

I created a simple table:
CREATE TABLE "ADVUPGRD"."GL_CAMPUSEMAILS"
("Campus" VARCHAR2(2 CHAR), "SEND_TO" VARCHAR2(60 CHAR), "SEND_CC"
VARCHAR2(250 CHAR), "SEND_BCC" VARCHAR2(60 CHAR))
The table got created, I can do select * from gl_campusemails and it gets me a blank row since I have not populated this table yet.
When I'm populating the table I'm using this:
INSERT INTO GL_CAMPUSEMAILS (Campus, Send_To, Send_CC, Send_BCC)
VALUES('CP', 'as#gmail.com', 'test#yahoo.com', 'test2#gmail.com');
but I got this error message:
Error starting at line : 8 in command -
INSERT INTO GL_CAMPUSEMAILS (Campus, Send_To, Send_CC, Send_BCC)
VALUES('CP', 'as#gmail.com', 'test#yahoo.com', 'test2#gmail.com')
Error at Command Line : 8 Column : 56
Error report -
SQL Error: ORA-00904: "SEND_BCC": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
I googled and found a lot of posting but they're mostly related to the use of reserved words in the select statement.
I don't think the columns I used in here belong to any reserved words.What did I do wrong in here
If you use double quotes while creating the table, the column names are created exactly as you typed, case sensitive; thus, you insert should be:
INSERT INTO GL_CAMPUSEMAILS(
"Campus",
"SEND_TO",
"SEND_CC",
"SEND_BCC"
)
VALUES (
'CP',
'as#gmail.com',
'test#yahoo.com',
'test2#gmail.com'
);
If you create the table with no quotes, this will work fine
CREATE TABLE GL_CAMPUSEMAILS
(
Campus VARCHAR2(2 CHAR),
SEND_TO VARCHAR2(60 CHAR),
SEND_CC VARCHAR2(250 CHAR),
SEND_BCC VARCHAR2(60 CHAR)
);
INSERT INTO GL_CAMPUSEMAILS(
Campus,
SEND_TO,
SEND_CC,
SEND_BCC
)
VALUES (
'CP',
'as#gmail.com',
'test#yahoo.com',
'test2#gmail.com'
);
Notice that not using double quotes, Oracle will consider all the objects with upper case names; so, for example, "CAMPUS", campus, CaMpUs will work, while "campus" will not

Missing parentheses in CREATE TABLE instruction

CREATE TABLE MAJEST_PROD_2015(
PRODUCT_ID CHAR(10) NOT NULL,
DESCRIPTION_PROD CHAR(30),
SEW_DATE DATE,
HARVEST_DATE DATE,
QUANTITY INT,
PROD_RATING INT(1),
PRIMARY KEY (PRODUCT_ID)
);
Error report -
SQL Error: ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Oracle is not MySQL so there is no INT(1) type:
CREATE TABLE MAJEST_PROD_2015(
PRODUCT_ID CHAR(10) NOT NULL,
DESCRIPTION_PROD CHAR(30),
SEW_DATE DATE,
HARVEST_DATE DATE,
QUANTITY INT,
PROD_RATING INT, -- here
PRIMARY KEY (PRODUCT_ID)
);
SqlFiddleDemo
If you don't need constant size of string, consider using VARCHAR2(30).
EDIT:
but i need those values to be between 1-5
So add check constraint:
CONSTRAINT chk_PROD_RATING CHECK (PROD_RATING BETWEEN 1 AND 5),
SqlFiddleDemo2
As already noted INT does not take a length constraint in Oracle - instead you could use NUMBER(1,0) which would restrict it to a single digit (-9 .. +9) and then you can further restrict it using a CHECK constraint.
CHAR(n) will also right pad the value with space (CHR(32)) characters so that it always contains the maximum number of characters. If you did not intend this then you should be using VARCHAR2(n) instead.
You also do not need a NOT NULL constraint on a column that is the PRIMARY KEY.
CREATE TABLE MAJEST_PROD_2015(
PRODUCT_ID VARCHAR2(10) CONSTRAINT MAJEST_PROD_2015__PROD_ID__PK PRIMARY KEY,
DESCRIPTION_PROD VARCHAR2(30),
SEW_DATE DATE,
HARVEST_DATE DATE,
QUANTITY INT,
PROD_RATING NUMBER(1,0) CONSTRAINT MAJEST_PROD_2015__PROD_RAT__CK CHECK ( PROD_RATING BETWEEN 1 AND 5 )
);
(also, should it be SEW_DATE or SOW_DATE? Since the next line talks about harvest then I would have thought "sow" was more apt.)

SQL Error: ORA-01722: invalid number

I have enclosed the table and the insert statement I am working on.
CREATE TABLE EMP (
DRIVER_ID INTEGER NOT NULL
, FNAME VARCHAR(30) NOT NULL
, LNAME VARCHAR(30) NOT NULL
, ADDRESS VARCHAR(50) NOT NULL
, SALARY VARCHAR(50) NOT NULL
, DOB DATE NOT NULL
, SHIFTS VARCHAR2(20) NOT NULL
, SSN CHAR(11) NOT NULL
, PHONE INTEGER NOT NULL
, HIRING_DATE DATE NOT NULL
, EMAIL VARCHAR2(50) NOT NULL
);
When I run this insert statement:
INSERT INTO EMP (DRIVER_ID, FNAME, LNAME, ADDRESS, SALARY, DOB, SHIFTS, SSN, PHONE, HIRING_DATE, EMAIL)
VALUES (SEQ_EMP.NEXTVAL,'Emma', 'Johnson', '123 Main Street', 'DIRECT DEPOSIT', '31 JANUARY,1988', 'MORNING', '579-45-6666', '410-555-1112', '16 DECEMBER,2013', 'ejohnson#fakemail.com');
I get this error message
SQL Error: ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
Lets look at this logically. The error message is saying "invalid number". Oracle is saying to you "I am expecting a number, but you gave me something that isn't a number".
Looking at the table SQL, you can see that the table has two columns whose type is a number type (actually INTEGER). These are DRIVER_ID and PHONE. (The other columns don't matter now ... because they won't expect a number as the value.)
Now look at the insert SQL, and the values corresponding to those columns.
The value inserted into the DRIVER_ID column comes from SEQ_EMP.NEXTVAL ... which I would assume has type INTEGER. That means, you won't get an error from there.
The value inserted into the PHONE column is '410-555-1112'. But, hey, that isn't a number. Its a string! And besides a (mathematical) number doesn't have hyphen characters embedded in it!
In short, if you are going to store phone numbers with - (or + or space) characters embedded in them, you can't use INTEGER as the column type.
In your table DDL change
PHONE INTEGER NOT NULL
to
PHONE CHAR(12) NOT NULL
as previously mentioned by user Stephen C using CHAR instead of INTEGER.
Also, those DATE fields will have to be converted to CHAR datatypes as well or you'll have to format your INSERT to handle the date format properly. Those fields are:
, DOB DATE NOT NULL
, HIRING_DATE DATE NOT NULL
If you chose to keep the columns as DATEs, then in your insert use (for the above-mentioned columns) the following...
,to_date('31-JANUARY-1988','DD-MONTH-YYYY')
,to_date('16-DECEMBER-2013','DD-MONTH-YYYY')
The above won't give you exactly what you are looking for -- e.g. 16 DECEMBER,2013 -- but it will work and format the date with hyphens -- e.g. 16-DECEMBER-2013. If you need further information on the to_date() function for Oracle for formatting and for other sundry information, please refer to the Oracle docs or search on "Oracle TO_DATE" via your favorite browser.
HTH

Insert query showing an error

I created a table in oracle10g using following query......
CREATE TABLE "MOBILELOCATION"
("EMPLOYEEID" NUMBER NOT NULL ENABLE,
"PRESENTDATE" VARCHAR2(30) NOT NULL ENABLE,
"PRESENTTIME" VARCHAR2(30) NOT NULL ENABLE,
"LATITUDE" NUMBER(6,10) NOT NULL ENABLE,
"LONGITUDE" NUMBER(6,10) NOT NULL ENABLE)
Table was created successfully... but the problem is while iam trying to insert a row into the table it is showing the error
error ORA-01438: value larger than specified precision allowed for this column
The query i used is ,
insert into mobilelocation values(12303,'30-10-2011','09:30',16.9876,82.3426);
Where i voilated the constraints?? Please explain any one..
Your columns LATITUDE and LONGTITUDE are defined rather strangely - NUMBER(6,10) says 6 for precision (total number of digits) and 10 for scale (number of digits to the right of the decimal point).
You either change them to NUMBER(*) or to NUMBER (10, 6) or NUMBER(*,4) or similar... the correct declaration is hard to guess but all mentioned would work with the sample data you provided...
For reference see http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/datatype.htm#i16209

Resources