Oracle 11.2.0.1.0 のドメイン インデックスの開発中に (問題は 12с にも表示されます)、indextype WITH ARRAY DMLオプションを作成する場合、 関数ODCIIndexInsertのパラメーター タイプの誤解に直面しました。
Oracleのドキュメントhttp://docs.oracle.com/cd/E11882_01/appdev.112/e10765/ext_idx_ref.htm#i76892によると
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
インデックスタイプは次のように作成されました
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.
だから私の質問はです。オラクルの通常の動作ですか(ドキュメントによると)?「WITH ARRAY DML」オプションを使用してINDEXTYPEを作成し、索引付けされた列のデータ型がNUMBERである場合のODCIIndexInsert関数の正しい署名は何ですか?
ちなみに、 「WITH ARRAY DML」オプションの署名なしでインデックスタイプを定義すると、明確で機能します。しかし、このアプローチはパフォーマンスのニーズを満たしていません。
また、オプション「WITH ARRAY DML WITHOUT COLUMN DATA」でインデックスタイプを定義し、署名を使用する場合
static function ODCIIndexInsert(ia sys.odciindexinfo, ridlist sys.odciridlist, env sys.ODCIEnv) return number
すべても機能します。しかし、このアプローチは私たちのビジネス ニーズを満たしません。
ドキュメントに従ってバッチ挿入が機能するように、ODCIIndexInsertパラメータ型(インデックス番号列の場合)を定義する方法はありますか?
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);