Новичок
Профиль
Группа: Участник
Сообщений: 1
Регистрация: 17.9.2013
Репутация: нет Всего: нет
|
Добрый день. Разрабатывая Domain Index для Oracle 11.2.0.1.0 (проблема также проявляется в 12c) с толкнулся с тем что немогу подобрать правильный тип для параметров функции ODCIIndexInsert в случае создания indextype с опцией with array dmlСогласно документацииВ случае WITH ARRAY DML Oracle будет вызвать ODCIIndexInsert ожидая следующую сигнатуру | Код | FUNCTION ODCIIndexInsert( ia ODCIIndexInfo, ridlist ODCIRidList, newvallist varray_of_column_type, env ODCIEnv) RETURN NUMBER
|
В моем случае индексируется столбец типа number соответсвенно я определил varray_of_column_type как sys.ODCINumberList| Код | STATIC FUNCTION ODCIIndexInsert(ia in sys.ODCIIndexInfo, ridlist in sys.ODCIRidList, newvallist in sys.ODCINumberList, env in SYS.ODCIEnv) RETURN NUMBER
|
Indextype создается с помощью команды | Код | CREATE INDEXTYPE test_index_type FOR test_eq(number, number) USING index_methods WITH ARRAY DML(number, sys.ODCINumberList) WITH LOCAL RANGE PARTITION WITH SYSTEM MANAGED STORAGE TABLES;
|
либо | Код | CREATE INDEXTYPE test_index_type FOR test_eq(number, number) USING index_methods WITH ARRAY DML WITH LOCAL RANGE PARTITION WITH SYSTEM MANAGED STORAGE TABLES;
|
(проблема проявляется и в том и в том случае) | Код | CREATE TABLE test_table (id NUMBER (19,0)); CREATE INDEX test_index ON test_table(id) INDEXTYPE IS test_index_type;
|
При попытке вставить в таблицу данные | Код | insert into test_table values (1);
|
Получаем ошибку Error starting at line 53 in command: insert into test_table values (1) Error at Command Line:53 Column:1 Error report: SQL Error: ORA-29925: cannot execute SCOTT.INDEX_METHODS.ODCIINDEXINSERT ORA-06553: PLS-306: wrong number or types of arguments in call to 'ODCIINDEXINSERT' ORA-06553: PLS-306: wrong number or types of arguments in call to 'ODCIINDEXINSERT' 29925. 00000 - "cannot execute %s" *Cause: The specified function does not exist or does not have an appropriate signature. *Action: Implement the function with the appropriate signature. Хотелось бы понять является ли такое поведение со стороны Субд Oracle корректным (соответствующим документации)? Как корректно определить сигнатуру метода ODCIIndexInsert что бы можно было создать индекс с опцией WITH ARRAY DML и иметь возможность осуществлять вставку данных в индекс в пакетированном режиме? При этом если определить indextype без опции WITH ARRAY DML сигнатура метода ODCIIndexInsert понятна и работает, однако такой режим не устаивает нас по соображениям производительности. Так же работает определение indextype c опцией WITH ARRAY DML without column data и сигнатурой | Код | static function ODCIIndexInsert(ia sys.odciindexinfo, ridlist sys.odciridlist, env sys.ODCIEnv) return number
|
Однако такая сигнатура не позволяет нам реализовать domain index в соответствии с нашими бизнес требованиями Соответственно интересует вопрос как правильно определить параметры функции ODCIIndexInsert (в случае индексации столбца типа number), что бы работала пакетированная вставка в соответствии с документацией : | Код | FUNCTION ODCIIndexInsert( ia ODCIIndexInfo, ridlist ODCIRidList, newvallist varray_of_column_type, env ODCIEnv)
|
Далее прилагается SQL позволяющий полностью воссоздать окружение для воспроизведения проблемы: ----- | Код | CREATE OR REPLACE TYPE index_methods AS OBJECT ( step number, STATIC FUNCTION ODCIGetInterfaces(ifclist OUT SYS.ODCIObjectList) RETURN NUMBER, STATIC FUNCTION ODCIIndexCreate (ia SYS.ODCIIndexInfo, parms VARCHAR2, env SYS.ODCIEnv) RETURN NUMBER, STATIC FUNCTION ODCIIndexAlter (ia sys.ODCIIndexInfo, parms IN OUT VARCHAR2, altopt number, env sys.ODCIEnv) RETURN NUMBER, STATIC FUNCTION ODCIIndexDrop(ia SYS.ODCIIndexInfo, env SYS.ODCIEnv) RETURN NUMBER, STATIC FUNCTION ODCIIndexExchangePartition(ia SYS.ODCIIndexInfo, ia1 SYS.ODCIIndexInfo, env SYS.ODCIEnv) RETURN NUMBER, STATIC FUNCTION ODCIIndexUpdPartMetadata(ia sys.ODCIIndexInfo, palist sys.ODCIPartInfoList, env sys.ODCIEnv) RETURN NUMBER, STATIC FUNCTION ODCIIndexInsert(ia in sys.ODCIIndexInfo, ridlist in sys.ODCIRidList, newvallist in sys.ODCINumberList, env in SYS.ODCIEnv) RETURN NUMBER, STATIC FUNCTION ODCIIndexDelete(ia SYS.ODCIIndexInfo, rid VARCHAR2, oldval number, env SYS.ODCIEnv) RETURN NUMBER, STATIC FUNCTION ODCIIndexUpdate(ia SYS.ODCIIndexInfo, rid VARCHAR2, oldval number, newval number, env SYS.ODCIEnv) RETURN NUMBER, STATIC FUNCTION ODCIIndexStart(sctx IN OUT index_methods, ia SYS.ODCIIndexInfo, op SYS.ODCIPredInfo, qi sys.ODCIQueryInfo, strt number, stop number, cmpval number, env SYS.ODCIEnv) RETURN NUMBER, MEMBER FUNCTION ODCIIndexFetch(self IN OUT index_methods, nrows NUMBER, rids OUT SYS.ODCIridlist, env SYS.ODCIEnv) RETURN NUMBER, MEMBER FUNCTION ODCIIndexClose(self IN index_methods, env SYS.ODCIEnv) RETURN NUMBER );
CREATE OR REPLACE TYPE BODY index_methods IS
STATIC FUNCTION ODCIGetInterfaces(ifclist OUT sys.ODCIObjectList) RETURN NUMBER IS BEGIN ifclist := sys.ODCIObjectList(sys.ODCIObject('SYS','ODCIINDEX2')); RETURN ODCIConst.Success; END ODCIGetInterfaces;
STATIC FUNCTION ODCIIndexCreate (ia sys.ODCIIndexInfo, parms VARCHAR2, env sys.ODCIEnv) RETURN NUMBER IS BEGIN RETURN ODCIConst.Success; END ODCIIndexCreate;
STATIC FUNCTION ODCIIndexDrop(ia sys.ODCIIndexInfo, env sys.ODCIEnv) RETURN NUMBER IS BEGIN RETURN ODCIConst.Success; END ODCIIndexDrop;
STATIC FUNCTION ODCIIndexAlter ( ia sys.ODCIIndexInfo, parms IN OUT VARCHAR2, altopt NUMBER, env sys.ODCIEnv) RETURN NUMBER IS BEGIN RETURN ODCIConst.Success; END ODCIIndexAlter;
STATIC FUNCTION ODCIIndexUpdPartMetadata( ia sys.ODCIIndexInfo, palist sys.ODCIPartInfoList, env sys.ODCIEnv) RETURN NUMBER IS BEGIN RETURN ODCIConst.Success; END ODCIIndexUpdPartMetadata;
STATIC FUNCTION ODCIIndexExchangePartition( ia sys.ODCIIndexInfo, ia1 sys.ODCIIndexInfo, env sys.ODCIEnv) RETURN NUMBER IS BEGIN RETURN ODCIConst.Success; END ODCIIndexExchangePartition;
STATIC FUNCTION ODCIIndexInsert( ia sys.ODCIIndexInfo, ridlist sys.ODCIRidList, newvallist sys.ODCINumberList, env sys.ODCIEnv) RETURN NUMBER IS BEGIN return ODCIConst.Success; END;
STATIC FUNCTION ODCIIndexDelete( ia SYS.ODCIIndexInfo, rid VARCHAR2, oldval number, env SYS.ODCIEnv) RETURN NUMBER IS BEGIN return ODCIConst.Success; END;
STATIC FUNCTION ODCIIndexUpdate( ia SYS.ODCIIndexInfo, rid VARCHAR2, oldval number, newval number, env SYS.ODCIEnv) RETURN NUMBER AS BEGIN return ODCIConst.Success; END;
STATIC FUNCTION ODCIIndexStart( sctx IN OUT index_methods, ia SYS.ODCIIndexInfo, op SYS.ODCIPredInfo, qi sys.ODCIQueryInfo, strt number, stop number, cmpval number, env SYS.ODCIEnv) RETURN NUMBER AS BEGIN sctx := index_methods(1); return ODCIConst.Success; END;
MEMBER FUNCTION ODCIIndexFetch( self IN OUT index_methods, nrows NUMBER, rids OUT SYS.ODCIridlist, env SYS.ODCIEnv) RETURN NUMBER AS BEGIN return ODCIConst.Success; END; MEMBER FUNCTION ODCIIndexClose(self IN index_methods, env SYS.ODCIEnv) RETURN NUMBER AS BEGIN return ODCIConst.Success; END;
end;
|
---- ------ | Код | --drop function test_eq_fun;
CREATE FUNCTION test_eq_fun(a number, b number) RETURN NUMBER AS BEGIN IF a = b then RETURN 1; ELSE RETURN 0; END IF; END;
--drop operator test_eq; CREATE OPERATOR test_eq BINDING (number, number) RETURN NUMBER USING test_eq_fun;
--drop indextype test_index_type; CREATE INDEXTYPE test_index_type FOR test_eq(number, number) USING index_methods WITH ARRAY DML(number, sys.ODCINumberList) WITH LOCAL RANGE PARTITION WITH SYSTEM MANAGED STORAGE TABLES;
/* CREATE INDEXTYPE test_index_type FOR test_eq(number, number) USING index_methods WITH ARRAY DML WITH LOCAL RANGE PARTITION WITH SYSTEM MANAGED STORAGE TABLES; */
--drop table test_table; CREATE TABLE test_table (id NUMBER (19,0));
CREATE INDEX test_index ON test_table(id) INDEXTYPE IS test_index_type;
insert into test_table values (1);
|
-----
|