Oracle table naming causes issues when inserting data - oracle

In Oracle 12c, I had a table named "CONTAINERS" and the following query was failing to insert data.
insert into CONTAINERS (ID,CONTAINER_NAME, HIERARCHY_SUB_TYPES_ID, HIERARCHY_TYPES_ID, SEGMENT_ID, SUB_SEGMENT_ID, USERS_ID_HIERARCHY_OWNER)
values (44,'ContainerName', 1, 1, 1, 1, 1);
Error:
Error at Command Line : 1 Column : 28 Error report - SQL Error:
ORA-02000: missing ) keyword
02000. 00000 - "missing %s keyword"
But this worked successfully
insert into CONTAINERS values (3,'ContainerName', 1, 1, 1, 1, 1);
I had to rename the table from "CONTAINERS" to "CONTAINER" for everything to work normally.
Can someone explain why I got this behavior?
DDL:
CREATE TABLE "RELANDHIER"."CONTAINERS"
( "ID" NUMBER,
"CONTAINER_NAME" VARCHAR2(200 BYTE),
"USERS_ID_HIERARCHY_OWNER" NUMBER,
"SEGMENT_ID" NUMBER,
"SUB_SEGMENT_ID" NUMBER,
"HIERARCHY_TYPES_ID" NUMBER,
"HIERARCHY_SUB_TYPES_ID" NUMBER
)

"CONTAINERS" seems to be a "reserved name". Here is my test case derived from yours :
drop table "DEMO"."CONTAINERS";
CREATE TABLE "DEMO"."CONTAINERS"
( "ID" NUMBER,
"CONTAINER_NAME" VARCHAR2(200 BYTE),
"USERS_ID_HIERARCHY_OWNER" NUMBER,
"SEGMENT_ID" NUMBER,
"SUB_SEGMENT_ID" NUMBER,
"HIERARCHY_TYPES_ID" NUMBER,
"HIERARCHY_SUB_TYPES_ID" NUMBER
);
insert into CONTAINERS (ID,CONTAINER_NAME, HIERARCHY_SUB_TYPES_ID, HIERARCHY_TYPES_ID, SEGMENT_ID, SUB_SEGMENT_ID, USERS_ID_HIERARCHY_OWNER)
values (44,'ContainerName', 1, 1, 1, 1, 1);
insert into "DEMO".CONTAINERS (ID,CONTAINER_NAME, HIERARCHY_SUB_TYPES_ID, HIERARCHY_TYPES_ID, SEGMENT_ID, SUB_SEGMENT_ID, USERS_ID_HIERARCHY_OWNER)
values (44,'ContainerName', 1, 1, 1, 1, 1);
INSERT only works if I prefix the owner schema to it.
Execution gives :
Table dropped.
Table created.
insert into CONTAINERS (ID,CONTAINER_NAME, HIERARCHY_SUB_TYPES_ID, HIERARCHY_TYPES_ID, SEGMENT_ID, SUB_SEGMENT_ID, USERS_ID_HIERARCHY_OWNER)
*
ERROR at line 1:
ORA-02000: missing ) keyword
1 row created.
Check this link to Oracle 12c new features

Related

The INSERT statement conflicted with the CHECK (len(column_name)) constraint

i'm new to SQL Sever
I'm trying to insert values into a table but keep getting the following error : The INSERT statement conflicted with the CHECK constraint "CK__Course__CourseCo__3A81B327". The conflict occurred in database "CustomerDB", table "dbo.Course", column 'CourseCode'.
create table Course (
CourseCode int check(len(CourseCode) =4 ),
Cdesc varchar(20),
TotalFeeCash money check(len(TotalFeeCash)=8),
TotalFeeInstallment money check(len(TotalFeeInstallment) =8),
MinDownPayment money check(len(MinDownPayment)= 8),
CourseType varchar(10),
Duration int check(len(Duration) = 4)
)
insert into Course(CourseCode,CDesc,TotalFeeCash,TotalFeeInstallment,MinDownPayment,CourseType,Duration)
values (1,'EACCP',55000,60000,10000,'full',36)
can we fix this without drop the constraint ? (i want to limit the input length to <=4) i've change the constraint check(len(CourseCode) =4 ) to check(len(CourseCode) <=4 ) but it still fail.

Oracle 12c using onDelete Trigger on Table with foreign key and onDelete cascade setNull throws ORA-00600: Internal Errorcode, Arguments: [13001]

.
Hello swarm intelligence, here's the problem, I can't seem to solve without a little help from the StackOverflow crowd :)
Given this Oracle Database
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit
Production PL/SQL Release 12.1.0.2.0 - Production
"CORE 12.1.0.2.0 Production" TNS for Solaris: Version 12.1.0.2.0 -
Production NLSRTL Version 12.1.0.2.0 - Production
And this DDL and data:
CREATE TABLE TR_TEST_HIST (
AUDIT_EVENT_TIMESTAMP date NOT NULL,
AUDIT_EVENT_TYPE char(1) NOT NULL,
ID number(19) NOT NULL,
BUSINESS_KEY varchar2(255) NOT NULL,
LINKED_ID number(19)
);
CREATE INDEX PK_TR_TEST_0 ON TR_TEST_HIST ( ID );
CREATE INDEX IDX_TR_TEST_0 ON TR_TEST_HIST ( LINKED_ID );
CREATE TABLE TR_TEST (
ID number(19) NOT NULL,
BUSINESS_KEY varchar2(255) NOT NULL,
LINKED_ID number(19) ,
CONSTRAINT PK_TR_TEST PRIMARY KEY ( ID )
);
CREATE INDEX IDX_TR_TEST ON TR_TEST ( LINKED_ID );
CREATE OR REPLACE TRIGGER TR_TEST_AUDIT_TRIGGER
BEFORE DELETE OR UPDATE ON TR_TEST
FOR EACH ROW
DECLARE
VAR_CHANGE_TYPE CHAR(1);
BEGIN
IF UPDATING THEN VAR_CHANGE_TYPE := 'U'; ELSE VAR_CHANGE_TYPE := 'D'; END IF;
INSERT INTO TR_TEST_HIST (AUDIT_EVENT_TIMESTAMP,
AUDIT_EVENT_TYPE,
BUSINESS_KEY,
ID,
LINKED_ID) VALUES (CURRENT_TIMESTAMP,
VAR_CHANGE_TYPE,
:OLD.BUSINESS_KEY,
:OLD.ID,
:OLD.LINKED_ID);
END TR_TEST_AUDIT_TRIGGER;
ALTER TABLE TR_TEST ADD CONSTRAINT FK_TR_TEST_LINKED FOREIGN KEY ( LINKED_ID ) REFERENCES TR_TEST( ID ) ON DELETE SET NULL;
INSERT INTO TR_TEST( ID, BUSINESS_KEY, LINKED_ID ) VALUES ( 4, 'entry_4', 3 );
INSERT INTO TR_TEST( ID, BUSINESS_KEY, LINKED_ID ) VALUES ( 3, 'entry_3', null );
INSERT INTO TR_TEST( ID, BUSINESS_KEY, LINKED_ID ) VALUES ( 1, 'entry_1', null );
INSERT INTO TR_TEST( ID, BUSINESS_KEY, LINKED_ID ) VALUES ( 2, 'entry_2', 1 );
When I run
DELETE FROM TR_TEST WHERE ID IN (1, 2);
statement execution fails with this error
[2019-09-10 18:01:51] [60000][600] ORA-00600: Interner Fehlercode,
Argumente: [13001], [], [], [], [], [], [], [], [], [], [], []
[2019-09-10 18:01:51] java.lang.RuntimeException: Error : 600,
Position : 12, Sql = DELETE FROM TR_TEST WHERE ID IN (1, 2),
OriginalSql = DELETE FROM TR_TEST WHERE ID IN (1, 2), Error Msg =
ORA-00600: Interner Fehlercode, Argumente: [13001], [], [], [], [],
[], [], [], [], [], [], []'
For the error message to occur, it makes no difference, if the audit trigger is BEFORE DELETE or AFTER DELETE.
But deleting everything one after another works and fills the audit table correctly
DELETE FROM TR_TEST WHERE ID IN (1);
DELETE FROM TR_TEST WHERE ID IN (2);
As well as deleting everything without WHERE clause, which also fills the audit table correctly
DELETE FROM TR_TEST;
The audit triggers also work, if one changes the foreign keys cascade rule to doNothing, but that is not the wanted behavior here.
Am I doing something wrong, or is this a real Oracle bug? Do you know any workaround?
Thanks for your help,
Marius
I have tested this on my Oracle XE 18c and have reproduced the problem. There's good news and bad news. The good news is I think I know what causes the error. The bad news is you're not going to like it.
The clue is in the time it takes for the trigger to hurl ORA-00600. It's a long time. This is often an indicator of recursion or a deadlock timeout. And that's what I think is happening here: when you delete a record the ON DELETE SET NULL clause executes an update. That causes the trigger to fire again (because it fires before delete or update), which executes another update and fires the trigger, and so on. Eventually the transaction fails with ORA-00600. If we drop that foreign key constraint not only does the delete succeed it finishes like that!. No time at all.
So it's definitely the ON DELETE SET NULL clause which is the problem. There's just something about deleting multiple rows in one statement which causes Oracle to blow a fuse. This shouldn't make a difference when we can delete each row individually but it does. That's what makes it a bug.
Anyway, at least you have a reproducible test case: Support likes those.

how to make distinct type with condition in oracle

create or replace TYPE PDV AS OBJECT
( percentage NUMBER(4,2),
MEMBER FUNCTION get_percentage RETURN NUMBER
) INSTANTIABLE NOT FINAL;
create or replace TYPE BODY PDV AS
MEMBER FUNCTION get_percentage RETURN NUMBER AS
BEGIN
return SELF.percentage;
END get_percentage;
END;
I have table Product (productID, name, description, percentage)
When I insert this in the database, it should be saved in the table Product:
insert into Product VALUES (1, 'Table', 'Brown table for six people.Made of oak', PDV(20.00));
When I insert this into the database, an error should occur:
insert into Product VALUES (1, 'Table', 'Brown table for six people.Made of oak', PDV(130.20));
I want to make distinct type with condition - percentage must be between 0 and 100. Where to put that condition?
percentage must be between 0 and 100. Where to put that condition?
Nowhere, I'd say. PERCENTAGE's data type, a numeric having precision 4 and scale 2 will take care about it.
As you didn't provide whole code you use, here's an example.
SQL> create or replace type pdv as object
2 (productid number,
3 name varchar2(30),
4 description varchar2(100),
5 percentage number(4, 2),
6 member function get_percentage return number
7 ) instantiable not final;
8 /
Type created.
SQL> create or replace type body pdv as
2 member function get_percentage return number as
3 begin
4 return self.percentage;
5 end get_percentage;
6 end;
7 /
Type body created.
SQL> create table product (prod pdv);
Table created.
SQL> insert into product values (pdv(1, 'Table', 'Made of oak', 20));
1 row created.
SQL> insert into product values (pdv(1, 'Table', 'Made of oak', 130));
insert into product values (pdv(1, 'Table', 'Made of oak', 130))
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
SQL> insert into product values (pdv(1, 'Table', 'Made of oak', 55.567));
1 row created.
SQL>
[EDIT, written after reading OP's comment]
I'm not sure I understood what you mean. If it means that you want to create an inline CHECK constraint, well, that won't work:
SQL> create or replace type pdv_typ as object
2 (
3 producid number,
4 name varchar2 (30),
5 description varchar2 (100),
6 percentage number (4, 2) constraint ch_perc check (percentage between 0 and 100),
7 member function get_percentage
8 return number
9 );
10 /
create or replace type pdv_typ as object
*
ERROR at line 1:
ORA-06545: PL/SQL: compilation error - compilation aborted
ORA-06550: line 6, column 29:
PLS-00103: Encountered the symbol "CONSTRAINT" when expecting one of the
following:
:= ) , not null default external character
ORA-06550: line 0, column 0:
PLS-00565: PDV_TYP must be completed as a potential REF target (object type)
SQL>
What you could do is to create a table whose column data type is of a previously created type, such as this:
SQL> create or replace type pdv_typ as object
2 (
3 producid number,
4 name varchar2 (30),
5 description varchar2 (100),
6 percentage number (4, 2),
7 member function get_percentage
8 return number
9 );
10 /
Type created.
SQL> create or replace type body pdv_typ
2 as
3 member function get_percentage
4 return number
5 as
6 begin
7 return self.percentage;
8 end get_percentage;
9 end;
10 /
Type body created.
SQL> create table pdv_tab
2 (
3 id number primary key,
4 pdv pdv_typ constraint ch_perc check (pdv.percentage between 0 and 100)
5 );
Table created.
SQL>
SQL> insert into pdv_tab values (1, pdv_typ (1, 'Table', 'Made of oak', 20));
1 row created.
SQL> insert into pdv_tab values (2, pdv_typ (2, 'Chair', 'Made of steel', 120));
insert into pdv_tab values (2, pdv_typ (2, 'Chair', 'Made of steel', 120))
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
SQL> insert into pdv_tab values (3, pdv_typ (3, 'Window', 'Made of glass', -5));
insert into pdv_tab values (3, pdv_typ (3, 'Window', 'Made of glass', -5))
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_PERC) violated
SQL>
Personally, I really, really don't like object side of Oracle. For me, it is a relational DBMS. Object support came as if they wanted to say hey, look, we can do that too!. I can't remember whether I ever used that functionality, except for educational purposes. Drawbacks? Plenty. Benefits? None. Once again, from my point of view.
So, what are you, really, doing? This is not a real-life problem, is it? That suggests your comment, saying that it has to be done that way. Says who? If it is a client, tell him to mind his own business. If it is a professor, then do what he says, regardless.
The straightforward way to do this would be a CHECK constraint on the table. That could be as simple as:
create table Product (
productID number primary key
, name varchar2(30) not null
, description varchar2(128) not null
, percentage number check (percentage between 0 and 100)
);
Demo in SQL Fiddle.

Trouble adding metadata to a table in Oracle

I created a table in Oracle with this code:
CREATE TABLE Roads (
TYPE VARCHAR2(40),
ADMN_CLASS VARCHAR2(20),
TOLL_RD VARCHAR2(10),
RTE_NUM1 VARCHAR2(3),
RTE_NUM2 VARCHAR2(3),
ROUTE VARCHAR2(40),
LOCATION MDSYS.SDO_GEOMETRY);
Then I wanted to add metadata to the LOCATION column which will hold the geometry:
INSERT INTO USER_SDO_GEOM_METADATA
(TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)
VALUES
('ROADS', 'LOCATION',
MDSYS.SDO_DIM_ARRAY
( MDSYS.SDO_DIM_ELEMENT('X', -180, 180, 0.5),
MDSYS.SDO_DIM_ELEMENT('Y', -90, 90, 0.5)
),
8256
);
However, I get an error:
Error report -
SQL Error: ORA-13223: duplicate entry for ROADS.LOCATION in SDO_GEOM_METADATA
ORA-06512: at "MDSYS.MD", line 1723
ORA-06512: at "MDSYS.MDERR", line 17
ORA-06512: at "MDSYS.SDO_GEOM_TRIG_INS1", line 48
ORA-04088: error during execution of trigger 'MDSYS.SDO_GEOM_TRIG_INS1'
13223. 00000 - "duplicate entry for %s in SDO_GEOM_METADATA"
*Cause: There are duplicate entries for the given table and column
value pair in the USER_SDO_GEOM_METADATA view.
*Action: Check that the specified table and geometry column names
are correct. There should be only one entry per table, geometry
column pair in the USER_SDO_GEOM_METADATA view.
I am not sure why it says there are duplicate values because I have not created this table before. It also tells me to make sure that table and column name is correct and they are.
I've created your table and executed your insert statement OK.
Once executed again, I was able to reproduce your problem.
The error "SQL Error: ORA-13223: duplicate entry for ROADS.LOCATION in SDO_GEOM_METADATA" definitely points to duplicate data.
This trigger MDSYS.SDO_GEOM_TRIG_INS1 just performs a count(*) validation on the following MDSYS table and raise the -13223 exception when rowcount is != 0 .
SQL> desc mdsys.SDO_GEOM_METADATA_TABLE
Name Null? Type
----------------------------------------- -------- ----------------------------
SDO_OWNER NOT NULL VARCHAR2(32)
SDO_TABLE_NAME NOT NULL VARCHAR2(32)
SDO_COLUMN_NAME NOT NULL VARCHAR2(1024)
SDO_DIMINFO MDSYS.SDO_DIM_ARRAY
SDO_SRID NUMBER
Query mdsys.SDO_GEOM_METADATA_TABLE in order to validate its contents. You should find the duplicate record:
SQL> select * from mdsys.SDO_GEOM_METADATA_TABLE ;
USER1
ROADS
LOCATION
SDO_DIM_ARRAY(SDO_DIM_ELEMENT('X', -180, 180, .5), SDO_DIM_ELEMENT('Y', -90, 90,
.5))
8256
To workaround this issue just delete that record from mdsys.SDO_GEOM_METADATA_TABLE.
I think the problem is because some space characters on the column_name.
COR_NB_SC_LON,COR_CD_EW_ LON
I have fixed it and it works.
insert into user_sdo_geom_metadata (table_name, column_name, diminfo, srid)
values (
'COORD_REF',
'myuser.CONVERT_DMS_TO_GEOM(COR_NB_DG_LON,COR_NB_MN_LON,COR_NB_SC_LON,COR_ CD_EW_LON,COR_NB_DG_LAT,COR_NB_MN_LAT,COR_NB_SC_LAT,COR_CD_NS_LAT)',
sdo_dim_array (
sdo_dim_element('long', -180.0, 180.0, 0.5),
sdo_dim_element('lat', -90.0, 90.0, 0.5)
),
4326
);
commit;

can not update user_sdo_geom_metadata when creating spatial database in oracle

i was using the oracle 11g and try to create a spatial database, i just copied the sample code from oracle document
but when it comes to update the metadata part, it gave a duplicate entry error, and i tried delete from user_sdo_geom_metadata and it didnot give any error, and then tried to insert again, still got the duplicate entry error. I also tried select * from user_sdo_geom_metadata but got nothing.
any one have idea why? thanks
THE sample code:
CREATE TABLE cola_markets (
mkt_id NUMBER PRIMARY KEY,
name VARCHAR2(32),
shape SDO_GEOMETRY);
INSERT INTO cola_markets VALUES(
1,
'cola_a',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,3), -- one rectangle (1003 = exterior)
SDO_ORDINATE_ARRAY(1,1, 5,7) -- only 2 points needed to
-- define rectangle (lower left and upper right) with
-- Cartesian-coordinate data
));
INSERT INTO user_sdo_geom_metadata
(TABLE_NAME,
COLUMN_NAME,
DIMINFO,
SRID)
VALUES (
'cola_markets',
'shape',
SDO_DIM_ARRAY( -- 20X20 grid
SDO_DIM_ELEMENT('X', 0, 20, 0.005),
SDO_DIM_ELEMENT('Y', 0, 20, 0.005)
),
NULL -- SRID
);
error cause: there are duplicate entries for the give table and column value pair in the user_sdo_geom_metadata view.
Just to be sure, what does the following show ?
SELECT * FROM USER_SDO_GEOM_METADATA;
Object names in dictionary views are stored in uppercase. So if you want to remove existing entries from the spatial metadata you need to do this (notice the uppper case table name):
DELETE FROM USER_SDO_GEOM_METADATA WHERE TABLE_NAME = 'COLA_MARKETS';
COMMIT;

Resources