Oracle CREATE spatial INDEX fails with "too many values" - oracle

When trying to create a spatial index on any SDO_GEOMETRY column (tried from multiple users, including SYS), Oracle fails with this statement:
Error at line 1
ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
ORA-00913: too many values
ORA-06512: at "MDSYS.SDO_INDEX_METHOD_10I", line 10
The database is quite old and creating spatial indexes worked in the past (there are already existing ones that work). A sample of creating an index we used:
CREATE TABLE TEST_SPATIAL_INDEX (FID NUMBER, GEOM SDO_GEOMETRY);
INSERT INTO USER_SDO_GEOM_METADATA
VALUES ( 'TEST_SPATIAL_INDEX', 'GEOM',
MDSYS.SDO_DIM_ARRAY(
MDSYS.SDO_DIM_ELEMENT('X', 601000, 619000, 0.1),
MDSYS.SDO_DIM_ELEMENT('Y', 6116000, 6142000, 0.1),
MDSYS.SDO_DIM_ELEMENT('Z', -200, 200, 0.1)),
NULL);
COMMIT;
create index TEST_SPATIAL_INDEX_1 on TEST_SPATIAL_INDEX(GEOM) indextype is mdsys.spatial_index;
Running statement:
select * from registry$history;
returns:
25-02-2015 11:54:06.449000
APPLY SERVER
11.2.0.3 0
Patchset 11.2.0.2.0
PSU
We have two instances (SIDs) under one server (same ORACLE HOME for both) and the other one works. We can't find any visible difference in NLS parameters or Oracle version etc that would set them apart. Any ideas what might be wrong?

It can be caused by 3rd party backup software - "IBM Tivoli Storage Manager for Databases". There is versions where after online backup database is left in invalid state.
However after restarting oracle service indexes can be created, until backup breaks it again.

Related

Duplicate Indexes error using Informatica 10.4

While running an informatica mapping in v10.4 I'm getting the following error.
The mapping essentially calls a complex stored procedure in Oracle to "swap out" a temporary file to a partitioned fact table.
CMN_1022 [
ORA-20014: FINISH_SP: ORA-20010: Duplicate Indexes: ORA-12801: error signaled in parallel query server P00I
ORA-06512: at "DIMDW.FACT_EXCHANGE_PARTITION_PKG", line 1650
ORA-20010: Duplicate Indexes: ORA-12801: error signaled in parallel query server P00I
ORA-06512: at "DIMDW.FACT_EXCHANGE_PARTITION_PKG", line 1292
ORA-12801: error signaled in parallel query server P00I
ORA-28604: table too fragmented to build bitmap index (172073921,57,56)
ORA-06512: at "DIMDW.FACT_EXCHANGE_PARTITION_PKG", line 1277
ORA-06512: at "DIMDW.FACT_EXCHANGE_PARTITION_PKG", line 1277
ORA-06512: at "DIMDW.FACT_EXCHANGE_PARTITION_PKG", line 1593
I do not know what this error means to Informatica.
Can anyone help me decipher it SPECIFIC TO INFORMATICA
The problem is specific to Oracle, so not sure how to make the answer specific to Informatica, especially without being able to see the details of what the workflow is trying to do.
The ORA-20014: FINISH_SP: ORA-20010: Duplicate Indexes: error is a custom message from the application code. The real key appears to be here: "ORA-28604: table too fragmented to build bitmap index (172073921,57,56)"
It looks like Informatica is attempting to build an index - indirectly through the DIMDW.FACT_EXCHANGE_PARTITION_PKG package - and the process is throwing an error. A simple Google search on ORA-28604 yields the following:
ORA-28604: table too fragmented to build bitmap index (%s,%s,%s)
*Cause: The table has one or more blocks that exceed the maximum number
of rows expected when creating a bitmap index. This is probably
due to deleted rows. The values in the message are:
(data block address, slot number found, maximum slot allowed)
*Action: Defragment the table or block(s). Use the values in the message
to determine the FIRST block affected. (There may be others).
Since this involves the physical fragmentation of the data in the Oracle database, you will almost certainly need to get the DBA involved to troubleshoot this further. Your Informatica workflow likely isn't going anywhere until this is corrected in the database.

Errors in creating spatial index on SDO_GEOMETRY column in oracle 11g

I am using Oracle 11g (Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production) and I have a table that has column of type SDO_GEOMETRY. I want to create a spatial index on this column (NEW_SHAPE). My query is as following:
CREATE INDEX GIS_GEOM_SRID3857_SPTIDX ON GIS_GEOM_SRID3857_LOOKUP ( NEW_SHAPE )
INDEXTYPE IS MDSYS.SPATIAL_INDEX;
/
and I am getting the following errors:
Error starting at line : 23 in command -
CREATE INDEX GIS_GEOM_SRID3857_SPTIDX ON GIS_GEOM_SRID3857_LOOKUP ( NEW_SHAPE )
INDEXTYPE IS MDSYS.SPATIAL_INDEX
Error report -
ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
ORA-13249: SRID 3857 does not exist in MDSYS.CS_SRS table
ORA-29400: data cartridge error
Error - OCI_NODATA
ORA-06512: at "MDSYS.SDO_INDEX_METHOD_10I", line 10
29855. 00000 - "error occurred in the execution of ODCIINDEXCREATE routine"
*Cause: Failed to successfully execute the ODCIIndexCreate routine.
*Action: Check to see if the routine has been coded correctly.
I have searched allot on these errors but have not found anything useful. I would highly appreciate if you may point me to the right direction and help in identifying the issue I am facing. It will save me allot of time. Many thanks in advance for your assistance.
First of all, your data must actually be SRID 3857 and sdo_geom.srid be set to 3857 for all rows of the table, for future processing to work.
Now, since the error raises, srid is set to 3857 in user_sdo_geom_metadata. So the question is: Does SRID 3857 exist in DB's SRIDs?
If not, you must insert it, drop the spatial index (usually a failed index gets created) and re-create it.
Let me know if you need any help on any of the above...

How to update an Oracle Table from SAS efficiently?

The problem I am trying to solve:
I have a SAS dataset work.testData (in the work library) that contains 8 columns and around 1 million rows. All columns are in text (i.e. no numeric data). This SAS dataset is around 100 MB in file size. My objective is to have a step to parse this entire SAS dataset into Oracle. i.e. sort of like a "copy and paste" of the SAS dataset from the SAS platform to the Oracle platform. The rationale behind this is that on a daily basis, this table in Oracle gets "replaced" by the one in SAS which will enable downstream Oracle processes.
My approach to solve the problem:
One-off initial setup in Oracle:
In Oracle, I created a table called testData with a table structure pretty much identical to the SAS dataset testData. (i.e. Same table name, same number of columns, same column names, etc.).
On-going repeating process:
In SAS, do a SQL-pass through to truncate ora.testData (i.e. remove all rows whilst keeping the table structure). This ensure the ora.testData is empty before inserting from SAS.
In SAS, a LIBNAME statement to assign the Oracle database as a SAS library (called ora). So I can "see" what's in Oracle and perform read/update from SAS.
In SAS, a PROC SQL procedure to "insert" data from the SAS dataset work.testData into the Oracle table ora.testData.
Sample codes
One-off initial setup in Oracle:
Step 1: Run this Oracle SQL Script in Oracle SQL Developer (to create table structure for table testData. 0 rows of data to begin with.)
DROP TABLE testData;
CREATE TABLE testData
(
NODENAME VARCHAR2(64) NOT NULL,
STORAGE_NAME VARCHAR2(100) NOT NULL,
TS VARCHAR2(10) NOT NULL,
STORAGE_TYPE VARCHAR2(12) NOT NULL,
CAPACITY_MB VARCHAR2(11) NOT NULL,
MAX_UTIL_PCT VARCHAR2(12) NOT NULL,
AVG_UTIL_PCT VARCHAR2(12) NOT NULL,
JOBRUN_START_TIME VARCHAR2(19) NOT NULL
)
;
COMMIT;
On-going repeating process:
Step 2, 3 and 4: Run this SAS code in SAS
******************************************************;
******* On-going repeatable process starts here ******;
******************************************************;
*** Step 2: Trancate the temporary Oracle transaction dataset;
proc sql;
connect to oracle (user=XXX password=YYY path=ZZZ);
execute (
truncate table testData
) by oracle;
execute (
commit
) by oracle;
disconnect from oracle;
quit;
*** Step 3: Assign Oracle DB as a libname;
LIBNAME ora Oracle user=XXX password=YYY path=ZZZ dbcommit=100000;
*** Step 4: Insert data from SAS to Oracle;
PROC SQL;
insert into ora.testData
select NODENAME length=64,
STORAGE_NAME length=100,
TS length=10,
STORAGE_TYPE length=12,
CAPACITY_MB length=11,
MAX_UTIL_PCT length=12,
AVG_UTIL_PCT length=12,
JOBRUN_START_TIME length=19
from work.testData;
QUIT;
******************************************************;
**** On-going repeatable process ends here *****;
******************************************************;
The limitation / problem to my approach:
The Proc SQL step (that transfer 100 MB of data from SAS to Oracle) takes around 5 hours to perform - the job takes too long to run!
The Question:
Is there a more sensible way to perform data transfer from SAS to Oracle? (i.e. updating an Oracle table from SAS).
First off, you can do the drop/recreate from SAS if that's a necessity. I wouldn't drop and recreate each time - a truncate seems easier to get the same results - but if you have other reasons then that's fine; but either way you can use execute (truncate table xyz) from oracle or similar to drop, using a pass-through connection.
Second, assuming there are no constraints or indexes on the table - which seems likely given you are dropping and recreating it - you may not be able to improve this, because it may be based on network latency. However, there is one area you should look in the connection settings (which you don't provide): how often SAS commits the data.
There are two ways to control this, the DBCOMMMIT setting and the BULKLOAD setting. The former controls how frequently commits are executed (so if DBCOMMIT=100 then a commit is executed every 100 rows). More frequent commits = less data is lost if a random failure occurs, but much slower execution. DBCOMMIT defaults to 0 for PROC SQL INSERT, which means just make one commit (fastest option assuming no errors), so this is less likely to be helpful unless you're overriding this.
Bulkload is probably my recommendation; that uses SQLLDR to load your data, ie, it batches the whole bit over to Oracle and then says 'Load this please, thanks.' It only works with certain settings and certain kinds of queries, but it ought to work here (subject to other conditions - read the documentation page above).
If you're using BULKLOAD, then you may be up against network latency. 5 hours for 100 MB seems slow, but I've seen all sorts of things in my (relatively short) day. If BULKLOAD didn't work I would probably bring in the Oracle DBAs and have them troubleshoot this, starting from a .csv file and a SQL*LDR command file (which should be basically identical to what SAS is doing with BULKLOAD); they should know how to troubleshoot that and at least be able to monitor performance of the database itself. If there are constraints on other tables that are problematic here (ie, other tables that too-frequently recalculate themselves based on your inserts or whatever), they should be able to find out and recommend solutions.
You could look into PROC DBLOAD, which sometimes is faster than inserts in SQL (though all in all shouldn't really be, and is an 'older' procedure not used too much anymore). You could also look into whether you can avoid doing a complete flush and fill (ie, if there's a way to transfer less data across the network), or even simply shrinking the column sizes.

How to solve Oracle 9i to 11g migration KOREAN_LEXER problems?

I currently work at migrating an Oracle 9i database (*.dmp file) to an Oracle 11g one.
To achieve this I use the exp and imp Oracle utilities command lines:
exp USERID=<user>/<password>#<database> FILE=<path> OWNER=<owner>
Then I create a skeleton.sql file which will create tables, index tables and finally indexes.
imp <user>/<password>#<database> FILE=<path> INDEXFILE="<path>\skeleton.sql" FROMUSER=<fromuser> TOUSER=<touser>
During this migration I am able to import most of the data correctly, and of course tablespaces are kept the same from one database to the other to avoid any conflicts.
But here comes the problem. In Oracle 11g, KOREAN_LEXER is no longer supported, instead you have to use the KOREAN_MORPH_LEXER. To do so I execute the following SQL commands:
call ctx_ddl.create_preference('korean_lexer','korean_morph_lexer');
call ctx_ddl.add_sub_lexer('global_lexer','korean','korean_lexer',null);
Then I import the skeleton.sql file in order to inject the data needed before the import:
sqlplus <user>/<password>#<database> #<path>\skeleton.sql
The creation of tables and index tables go smoothly until I get the following error for each of the 150+ indexes I created:
CREATE INDEX "<schema>"."WORKORDER_NDX16" ON "WORKORDER"
ERROR at line 1 :
ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
ORA-20000: Oracle Text error:
DRG-10502: WORKORDER_NDX16 index does not exist
DRG-13201: KOREAN_LEXER is no longer supported
ORA-06512: at "CTXSYS.DRUE", line 160
ORA-06512: at "CTXSYS.TEXTINDEXMETHODS", line 366
Indexes are still created, this message is just a warning.
I try to rebuild any of the broken indexes:
ALTER index WORKORDER_NDX16 REBUILD;
Which give me the following error again:
SQL Error : ORA-29874: warning in the execution of ODCIINDEXCREATE routine
ORA-29960: ligne 1,
DRG-10595: failure on ALTER INDEX WORKORDER_NDX16
DRG-50857: oracle error in drixmd.PurgeKGL
ORA-20000: Oracle Text error:
DRG-13201: KOREAN_LEXER is no longer supported
ORA-30576: ConText Option dictionary loading error
DRG-50610: internal error: kglpurge []
29874. 00000 - "warning in the execution of ODCIINDEXALTER routine"
*Cause: A waring was returned from the ODCIIndexAlter routine.
*Action: Check to see if the routine has been coded correctly
Check the user defined warning log tables for greater details.
In my skeleton.sql file, under the creation of each indexes, I have the following lines for each language:
ctxsys.driimp.set_object('LEXER','MULTI_LEXER',12);
...
ctxsys.driimp.set_sub_value('SUB_LEXER','8', NULL, NULL,'KO:KOREAN_LEXER:');
...
So far I am lost on what to do, this seems to be a simple issue to solve but my dba skills are too low to do this on my own.
If anyone could help me on this I would greatly appreciate it !
Thank you.
This looks like your database is using Oracle Text indexes, which are not the same as ordinary indexes. Have you followed completely Oracle Note 300172.1 (Obsolescence of KOREAN_LEXER Lexer Type)? It mentions this code below, which could help.
ALTER INDEX <[schema.]index> REBUILD
PARAMETERS('REPLACE LEXER ko_morph_lexer [MEMORY <size>]');
If all else fails, maybe consider trying to migrate your data into an Oracle 10g database and complete the korean_morph_lexer in 10g. If that works, it would be an easy Data Pump task to move it from 10g to 11g (or 12c).

Operation must be an updateable query - VB Script, Paradox Table

I'm using a Win XP box with BDE Administrator and Access 2007 installed. I'm able to open and perform select queries on existing Paradox tables without problem but have some very strange behavior when attempting INSERT/UPDATE. I can even create a new Paradox table and it has the same behavior. Here is sample code:
' create new table
conObj.Execute "CREATE TABLE test (id INT, comment VARCHAR(30))"
' first insert works fine
conObj.Execute "INSERT INTO test VALUES (1, 'something')"
' second insert fails for unknown reason
conObj.Execute "INSERT INTO test VALUES (2, 'something else')"
I've tried using Jet 4.0, MS Access Paradox driver, and native Paradox driver connection strings but all yield the same result. On the second insert statement it throws an error:
Operation must be an updateable query
I've read numerous posts in forums and pages on help sites that tell me this error is caused by a file permissions issue. The account running this script is part of the Administrator group and I've changed file permissions to allow the Everyone group Full Control of the db file but this changes nothing.
This page put out by Micrsoft Support did not fix the problem: http://support.microsoft.com/kb/175168
Additionally, I can create a new table but any time I try to create a PRIMARY KEY or UNIQUE field I get an error message that says:
"Index_[random characters] is not a valid name."
try
"CREATE TABLE test (id INT, comment VARCHAR(30), primary key(id))"
I don't know much about Paradox databases but this has indeed been a learning experience. Even though I have a table file called table.db that's not enough to store more than a single row of data. I also need several other files to insert or update a paradox database:
table.DB
table.PX
table.VAL
table.XG0
table.XG1
table.YG0
table.YG1
I was nosing around in another program that generates paradox databases and found when I copied a blank database from it along with these other files it generated I was able to insert and update without problems. I have no idea what these files are for or why they need to be present to insert or update but having them present fixed my issue.

Resources