extensible_index
create user ex identified by oracle;
grant Resource to ex;
grant connect to ex;
grant create view to ex;
grant create operator to ex;
grant create indextype to ex;
--1 创建测试用的数据表:
create table TTT
(
PID INTEGER not null,
PERSIONID VARCHAR2(18),
RPERSIONID VARCHAR2(100),
NAME VARCHAR2(10),
RNAME VARCHAR2(100),
BALANCE NUMBER
);
insert into ttt(pid,rpersionid,rname) select 1,'430268198905018260','李' from dual;
insert into ttt(pid,rpersionid,rname) select 1,'2','李1' from dual;
commit;
--2 创建辅助的Oracle包
CREATE OR REPLACE PACKAGE power_pkg AS
is_debug number := 0;
TYPE rowidcur IS REF CURSOR;
/*
编码函数-单条记录,自己去想招,最重要能保持有序(可以搞个一字节变多字节算法)
有些特殊字符还得考虑一下
*/
FUNCTION Encode(p_base64 IN VARCHAR2) RETURN VARCHAR2;
/*
BASE64解码函数-单条
*/
FUNCTION Decode(p_base64 IN VARCHAR2) RETURN VARCHAR2;
FUNCTION getversion(idxschema IN VARCHAR2,
idxname IN VARCHAR2,
newblock OUT PLS_INTEGER) RETURN VARCHAR2;
PROCEDURE checkversion(version IN VARCHAR2);
PROCEDURE ODC_Print(in_print_str IN VARCHAR2);
FUNCTION ODC_SetDebug(in_isdebug IN NUMBER) RETURN NUMBER;
--添加一个casttoraw的函数索引
PROCEDURE Proc_AddNativeIndex(in_SchemaName IN VARCHAR2,
in_TableName IN VARCHAR2,
in_FieldName IN VARCHAR2,
in_Unique IN NUMBER DEFAULT 0,
in_IndexName IN VARCHAR2 DEFAULT NULL);
--干掉这个本地的函数索引
PROCEDURE Proc_DropNativeIndex(in_SchemaName IN VARCHAR2,
in_TableName IN VARCHAR2
);
END power_pkg;
/
CREATE OR REPLACE PACKAGE BODY power_pkg AS
-- iterate is a package-level variable used to maintain state across calls
-- by Export in this session.
iterate NUMBER := 0;
/*
编码函数-单条记录,自己去想招,最重要能保持有序(可以搞个一字节变多字节算法)
有些特殊字符还得考虑一下
*/
FUNCTION Encode(p_base64 IN VARCHAR2) RETURN VARCHAR2
IS
l_len PLS_INTEGER;
l_base64 VARCHAR2(32767) := p_base64;
l_raw VARCHAR2(32767);--raw(24576);
-- base64 values
base64_before PLS_INTEGER;
base64_after PLS_INTEGER;
result_base PLS_INTEGER;
BEGIN
NULL;
RETURN UTL_RAW.cast_to_varchar2(l_raw);
END Encode;
/*
BASE64解码函数-单条
*/
FUNCTION Decode(p_base64 IN VARCHAR2) RETURN VARCHAR2
IS
l_len PLS_INTEGER;
l_base64 VARCHAR2(32767) := p_base64;
l_raw VARCHAR2(32767);--raw(24576);
-- base64 values
base64_before PLS_INTEGER;
base64_after PLS_INTEGER;
result_base PLS_INTEGER;
BEGIN
NULL;
RETURN UTL_RAW.cast_to_varchar2(l_raw);
END Decode;
FUNCTION getversion(idxschema IN VARCHAR2,
idxname IN VARCHAR2,
newblock OUT PLS_INTEGER) RETURN VARCHAR2 IS
BEGIN
-- We are generating only one PL/SQL block consisting of one line of code.
newblock :=1;
IF iterate =0 THEN
-- Increment iterate so we'll know we're done next time we're called.
iterate := iterate +1;
-- Return a string that calls checkversion with a version 'V1.0'
-- Note that export adds the surrounding BEGIN/END pair to form the anon.
-- block... we don't have to.
--RETURunistr('\0070\006F\0077\0065\0072\005F\0070\006B\0067\002E\0063\0068\0065\0063\006B\0076\0065\0072\0073\0069\006F\006E\0028\0027\0056\0031\002E\0030\0027\0029\003B');
RETURN unistr('\0070\006F\0077\0065\0072\005F\0070\006B\0067\002E\0063\0068\0065\0063\006B\0076\0065\0072\0073\0069\006F\006E\0028\0027\0056\0031\002E\0030\0027\0029\003B');
ELSE
-- reset iterate for next index
iterate :=0;
-- Return a 0-length string; we won't be called again for this index.
RETURN '';
END IF;
END getversion;
--检查版本号
PROCEDURE checkversion(version IN VARCHAR2)IS
wrong_version EXCEPTION;
BEGIN
IF version !='V1.0' THEN
RAISE wrong_version;
END IF;
END checkversion;
--打印调试信息
PROCEDURE ODC_Print(in_print_str IN VARCHAR2) IS
BEGIN
IF is_debug=0 then
RETURN;
ELSE
DBMS_OUTPUT.PUT_LINE(in_print_str);
END IF;
END ODC_Print;
--决定是否打印调试信息
FUNCTION ODC_SetDebug(in_isdebug IN NUMBER) RETURN NUMBER IS
BEGIN
is_debug := in_isdebug;
return is_debug;
END ODC_SetDebug;
PROCEDURE Proc_AddNativeIndex(in_SchemaName IN VARCHAR2,
in_TableName IN VARCHAR2,
in_FieldName IN VARCHAR2,
in_Unique IN NUMBER DEFAULT 0,
in_IndexName IN VARCHAR2 DEFAULT NULL
)
AS
PRAGMA AUTONOMOUS_TRANSACTION;
l_indexsql VARCHAR2(512):='';
l_indexname VARCHAR2(30):='';
--l_nativeindex VARCHAR2(30):='';
--l_domainindex VARCHAR2(30):='';
--l_fieldid PLS_INTEGER:=0;
--l_checkindex_sql VARCHAR2(512):='';
--l_insert_sql VARCHAR2(512):='';
--my_cur rowidcur;
l_object_maxlen PLS_INTEGER:=30;
--l_havenativeindex PLS_INTEGER:=0;
l_retnum PLS_INTEGER:=0;
BEGIN
IF in_IndexName IS NOT NULL THEN
l_indexname:=in_IndexName;
ELSE
l_indexname:='IDX#'||dbms_random.string('X',6);
END IF;
--l_indexname:='IDX#'||l_fieldid;
IF lengthb(l_indexname)>l_object_maxlen THEN
l_indexname:='IDX#'||dbms_random.string('X',14);
END IF;
--创建相关的函数索引
IF in_Unique>0 THEN
--是唯一性索引,无论是否有分区,都要创建全局索引
l_indexsql:='CREATE UNIQUE INDEX '||in_SchemaName||'.'||l_indexname||' ON ';
--IF COFFER.ODC_PACK_EIMANAGER.Func_CheckCanUseFBI(l_fieldid)=1 THEN
l_indexsql:=l_indexsql||in_SchemaName||'.'||in_TableName||'FUNC_INDEX('||in_FieldName||'))';
ELSE
l_indexsql:='CREATE INDEX '||in_SchemaName||'.'||l_indexname||' ON ';
l_indexsql:=l_indexsql||in_SchemaName||'.'||in_TableName||'(FUNC_INDEX('||in_FieldName||'))';
END IF;
ODC_Print(l_indexsql);
EXECUTE IMMEDIATE l_indexsql;
END Proc_AddNativeIndex;
--干掉这个本地的函数索引
PROCEDURE Proc_DropNativeIndex(in_SchemaName IN VARCHAR2,
in_TableName IN VARCHAR2
)
AS
l_nativeIndexName VARCHAR2(32) :='';
l_sql VARCHAR2(2000) :='';
BEGIN
select t1.index_name INTO l_nativeIndexName from user_indexes t1
where t1.index_type='FUNCTION-BASED NORMAL' and t1.table_name=in_TableName;
IF l_nativeIndexName ='' THEN
RETURN;
ELSE
--有兴趣的童鞋去实现一下吧,找个中间存一下,然后再查
--l_sql:='drop index '||in_SchemaName||'.'||l_nativeIndexName;
null;
END IF;
POWER_PKG.ODC_Print(l_sql);
execute immediate l_sql;
END Proc_DropNativeIndex;
END power_pkg;
/
--3 创建三个中间的辅助函数
CREATE OR REPLACE FUNCTION rawTovar(acc_var IN varchar2)
RETURN varchar2 DETERMINISTIC
IS acc_bal VARCHAR2(2000);
BEGIN
acc_bal:=UTL_RAW.cast_to_varchar2(acc_var);
RETURN(acc_bal);
END;
/
CREATE OR REPLACE FUNCTION func_index(acc_var IN varchar2)
RETURN varchar2 DETERMINISTIC
IS acc_bal VARCHAR2(2000);
BEGIN
acc_bal:=power_pkg.encode(utl_raw.cast_to_varchar2(acc_var));
RETURN(acc_bal);
END;
/
CREATE OR REPLACE FUNCTION varToRaw(acc_var IN varchar2)
RETURN varchar2 DETERMINISTIC
IS acc_bal VARCHAR2(2000);
BEGIN
acc_bal:=UTL_RAW.cast_to_raw(acc_var);
RETURN(acc_bal);
END;
/
--4 创建索引类型
--没有太多好的,固定定义,但是有些的函数参数是比较灵活的,可以综合利用
CREATE OR REPLACE TYPE power_idxtype_im AS OBJECT
(
curnum NUMBER,
howmany NUMBER,
cacheflag INTEGER,
scan_curnum NUMBER,
scan_fetchnum 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 ODCIIndexDrop(ia sys.ODCIIndexInfo, env sys.ODCIEnv)
RETURN NUMBER,
STATIC FUNCTION ODCIIndexStart(sctx IN OUT power_idxtype_im,
ia sys.ODCIIndexInfo,
op sys.ODCIPredInfo,
qi sys.ODCIQueryInfo,
strt VARCHAR2,
stop VARCHAR2,
env sys.ODCIEnv) RETURN NUMBER,
MEMBER FUNCTION ODCIIndexFetch(
self IN OUT POWER_IDXTYPE_IM,
nrows NUMBER,
rids OUT sys.ODCIRidList,
env sys.ODCIEnv) RETURN NUMBER,
MEMBER FUNCTION ODCIIndexClose(env sys.ODCIEnv)RETURN NUMBER,
STATIC FUNCTION ODCIIndexInsert(ia sys.ODCIIndexInfo,
rid VARCHAR2,
env sys.ODCIEnv) RETURN NUMBER,
STATIC FUNCTION ODCIIndexDelete(ia sys.ODCIIndexInfo,
rid VARCHAR2,
env sys.ODCIEnv) RETURN NUMBER,
STATIC FUNCTION ODCIIndexUpdate(ia sys.ODCIIndexInfo,
rid VARCHAR2,
env sys.ODCIEnv) RETURN NUMBER,
STATIC FUNCTION ODCIIndexGetMetadata(ia sys.ODCIIndexInfo,
expversion VARCHAR2,
newblock OUT PLS_INTEGER,
env sys.ODCIEnv)
RETURN VARCHAR2
);
/
CREATE OR REPLACE TYPE BODY power_idxtype_im 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
l_schemaname VARCHAR2(32):='';
l_tablename VARCHAR2(32):='';
l_fieldname VARCHAR2(32):='';
l_indexname VARCHAR2(32):='';
l_category NUMBER:=0;
l_isunique NUMBER:=0;
l_tablepartition VARCHAR2(32):='';
l_indexpartition VARCHAR2(32):='';
BEGIN
sys.ODCIIndexInfoDump(ia);
IF UPPER(parms)='UNIQUE' THEN
l_isunique:=1;
END IF;
l_schemaname:=ia.IndexCols(1).TableSchema;
l_tablename:=ia.IndexCols(1).TableName;
l_fieldname:=replace(ia.IndexCols(1).ColName,'"','');
l_indexname:=ia.IndexName;
POWER_PKG.ODC_Print('SCHEMA:'||l_schemaname);
POWER_PKG.ODC_Print('TABLE:'||l_tablename);
POWER_PKG.ODC_Print('FIELD:'||l_fieldname);
POWER_PKG.ODC_Print('INDEX NAME:'||l_indexname);
IF UPPER(parms)='NODATA' THEN
--不生成索引数据,直接返回成功
POWER_PKG.ODC_Print('ODCIIndexCreate<<<<<');
RETURN ODCICONST.SUCCESS;
ELSE
--底层函数索引的名为随机字符串
POWER_PKG.Proc_AddNativeIndex(
in_SchemaName => l_schemaname,
in_TableName => l_tablename,
in_FieldName => l_fieldname,
in_Unique => l_isunique,
in_Indexname => '');
END IF;
RETURN ODCICONST.SUCCESS;
END ODCIIndexCreate;
STATIC FUNCTION ODCIIndexDrop(ia sys.ODCIIndexInfo, env sys.ODCIEnv)
RETURN NUMBER IS
l_exec_sql VARCHAR2(2000);
l_schemaname VARCHAR2(32):='';
l_tablename VARCHAR2(32):='';
l_fieldname VARCHAR2(32):='';
l_indexname VARCHAR2(32):='';
--cnum INTEGER;
--junk INTEGER;
BEGIN
-- Construct the SQL statement.
POWER_PKG.ODC_Print('sys.ODCIIndexInfoDump(ia);');
sys.ODCIIndexInfoDump(ia);
--sys.Odcienvdump(env);
l_schemaname:=ia.IndexCols(1).TableSchema;
l_tablename:=ia.IndexCols(1).TableName;
l_fieldname:=replace(ia.IndexCols(1).ColName,'"','');
l_indexname:=ia.IndexName;
POWER_PKG.ODC_Print('SCHEMA:'||l_schemaname);
POWER_PKG.ODC_Print('TABLE:'||l_tablename);
POWER_PKG.ODC_Print('FIELD:'||l_fieldname);
POWER_PKG.ODC_Print('INDEX NAME:'||l_indexname);
--先干掉这个domainIndex
l_exec_sql:='drop index '||l_schemaname||'.'||l_indexname;
execute immediate l_exec_sql;
--然后跟着干掉这个函数索引
POWER_PKG.Proc_DropNativeIndex(in_SchemaName => l_schemaname,
in_TableName => l_tablename);
RETURN ODCICONST.SUCCESS;
END ODCIIndexDrop;
STATIC FUNCTION ODCIIndexStart(sctx IN OUT power_idxtype_im,
ia sys.ODCIIndexInfo,
op sys.ODCIPredInfo,
qi sys.ODCIQueryInfo,
strt VARCHAR2,
stop VARCHAR2,
env sys.ODCIEnv) RETURN NUMBER IS
cnum INTEGER;
rid ROWID;
nrows INTEGER;
relop VARCHAR2(2);
stmt VARCHAR2(1000);
conditionstr varchar2(100):='';
l_schemaname VARCHAR2(32):='';
l_tablename VARCHAR2(32):='';
l_fieldname VARCHAR2(32):='';
BEGIN
--完成一些初如化工作
POWER_PKG.ODC_Print('ODCIIndexStart>>>>>');
sys.ODCIIndexInfoDump(ia);
POWER_PKG.ODC_Print('start key : ' || strt);
POWER_PKG.ODC_Print('stop key : ' || stop);
POWER_PKG.ODC_Print('dump ENV,dump op,dump qi');
--sys.Odcienvdump(env);
sys.ODCIPredInfoDump(op);
--sys.Odciqueryinfodump(qi);
--获取相关的模式名、表名、字段名
l_schemaname:=ia.IndexCols(1).TableSchema;
l_tablename:=ia.IndexCols(1).TableName;
l_fieldname:=replace(ia.IndexCols(1).ColName,'"','');
--接下来才是真正的开工
--如查是精确查询
IF (bitand(op.Flags, ODCIConst.PredExactMatch)
= ODCIConst.PredExactMatch)
THEN
conditionstr := POWER_PKG.encode(strt);
stmt := 'select /*+First_rows */rowid from '||l_schemaname||'.'||l_tablename||' where '
||'POWER_PKG.FUNC_INDEX('||l_fieldname||')='''||conditionstr||'''';
POWER_PKG.ODC_Print(stmt);
cnum := dbms_sql.open_cursor;
dbms_sql.parse(cnum, stmt, dbms_sql.native);
-- Set context as the cursor number.
sctx := POWER_IDXTYPE_IM(cnum,0,0,0,0);
ELSE
--如果是模糊查询,而且当前只支持到这个前缀的查询
IF (bitand(op.Flags, ODCIConst.PredPrefixMatch)
= ODCIConst.PredPrefixMatch)
THEN
conditionstr:=substr(strt,1,length(strt)-1);
--******************************************************************************************************************
--by zhuyj
--conditionstr := COFFER.odc_pack_fi.encode(conditionstr);
stmt :='select /*+First_rows */rowid from '||l_schemaname||'.'||l_tablename||' where '
||'POWER_PKG.FUNC_INDEX('||l_fieldname||') like '''||conditionstr||'%''';
POWER_PKG.ODC_Print(stmt);
cnum := dbms_sql.open_cursor;
dbms_sql.parse(cnum, stmt, dbms_sql.native);
-- Set context as the cursor number.
sctx := POWER_IDXTYPE_IM(cnum,0,0,0,0);
ELSE
POWER_PKG.ODC_Print('暂时只支持等值与模糊查询,其他条件查询,自己去查相关资料');
END IF;
END IF;
POWER_PKG.ODC_Print('native searchSQL='||stmt);
RETURN ODCICONST.SUCCESS;
END ODCIIndexStart;
MEMBER FUNCTION ODCIIndexFetch(self IN OUT POWER_IDXTYPE_IM,
nrows NUMBER,
rids OUT sys.ODCIRidList,
env sys.ODCIEnv) RETURN NUMBER IS
cnum INTEGER;
idx INTEGER := 1;
rlist sys.ODCIRidList := sys.ODCIRidList();
done boolean := FALSE;
l_rid ROWID:='';
rid_tab DBMS_SQL.Varchar2_Table;
r_num INTEGER:=0;
counter INTEGER:=1;
l_totalcost INTEGER:=0;
l_getnum_const INTEGER:=200;
BEGIN
POWER_PKG.ODC_Print('ODCIIndexFetch>>>>>');
POWER_PKG.ODC_Print('Nrows : ' || round(nrows));
cnum := self.curnum;
--官方方式
/*
WHILE not done LOOP
if idx > nrows then
done := TRUE;
else
rlist.extEND;
if dbms_sql.fetch_rows(cnum) > 0 then
dbms_sql.column_value_rowid(cnum, 1, rlist(idx));
idx := idx + 1;
else
rlist(idx) := null;
done := TRUE;
END if;
END if;
END LOOP;
*/
--coffer方式
IF self.howmany =0 THEN
dbms_sql.define_array(cnum,1, rid_tab, l_getnum_const,1);
--dbms_sql.define_array(cnum, 1, rid_tab, nrows, 1);
r_num := DBMS_SQL.EXECUTE(cnum);
--DBMS_OUTPUT.put_line('r_num='||r_num);
END IF;
r_num := DBMS_SQL.FETCH_ROWS(cnum);
--Odc_Pack_Util.ODC_Print('num:'||r_num,1);
IF r_num = l_getnum_const THEN
rlist.extend(r_num);
ELSE
rlist.extend(r_num+1);
--rlist(r_num+1):=NULL;
END IF;
DBMS_SQL.COLUMN_VALUE(cnum,1, rid_tab);
--COFFER.ODC_PACK_UTIL.ODC_Print('rid_tab:'||rid_tab.count||' '||rid_tab.first);
for i in 1..r_num loop
rlist(i) := rid_tab(i+SELF.howmany);
--rlist(i) := rid_tab(i);
--COFFER.ODC_PACK_UTIL.ODC_Print('rlist(i):'||rlist(i));
end loop;
--IF r_num != l_getnum_const THEN
--rlist(r_num+1):=NULL;
--ELSE
SELF.howmany :=SELF.howmany + r_num;
--end coffer type
rids := rlist;
RETURN ODCICONST.SUCCESS;
END ODCIIndexFetch;
MEMBER FUNCTION ODCIIndexClose(env sys.ODCIEnv) RETURN NUMBER IS
cnum INTEGER;
BEGIN
POWER_PKG.ODC_Print('ODCIIndexClose>>>>>');
cnum := self.curnum;
dbms_sql.close_cursor(cnum);
RETURN ODCICONST.SUCCESS;
END ODCIIndexClose;
STATIC FUNCTION ODCIIndexInsert(ia sys.ODCIIndexInfo,
rid VARCHAR2,
env sys.ODCIEnv) RETURN NUMBER AS
cid INTEGER;
i BINARY_INTEGER;
nrows INTEGER;
stmt VARCHAR2(1000);
BEGIN
POWER_PKG.ODC_Print(' ');
sys.ODCIIndexInfoDump(ia);
-- Construct the statement,just do nothing
RETURN ODCICONST.SUCCESS;
END ODCIIndexInsert;
STATIC FUNCTION ODCIIndexDelete(ia sys.ODCIIndexInfo,
rid VARCHAR2,
env sys.ODCIEnv) RETURN NUMBER AS
cid INTEGER;
stmt VARCHAR2(1000);
nrows INTEGER;
BEGIN
POWER_PKG.ODC_Print(' ');
sys.ODCIIndexInfoDump(ia);
-- Construct the statement,just do nothing
RETURN ODCICONST.SUCCESS;
END ODCIIndexDelete;
STATIC FUNCTION ODCIIndexUpdate(ia sys.ODCIIndexInfo,
rid VARCHAR2,
env sys.ODCIEnv) RETURN NUMBER AS
cid INTEGER;
cid2 INTEGER;
stmt VARCHAR2(1000);
stmt2 VARCHAR2(1000);
nrows INTEGER;
i NUMBER;
BEGIN
POWER_PKG.ODC_Print(' ');
sys.ODCIIndexInfoDump(ia);
-- Delete old entries,just do nothing
RETURN ODCICONST.SUCCESS;
END ODCIIndexUpdate;
STATIC FUNCTION ODCIIndexGetMetadata(ia sys.ODCIIndexInfo,
expversion VARCHAR2,
newblock OUT PLS_INTEGER,
env sys.ODCIEnv)
RETURN VARCHAR2 IS
BEGIN
-- Let getversion do all the work since it has to maintain state across calls.
RETURN power_pkg.getversion(ia.IndexSchema, ia.IndexName, newblock);
EXCEPTION
WHEN OTHERS THEN
RAISE;
END ODCIIndexGetMetaData;
END;
/
--5 创建操作符
CREATE or replace OPERATOR odc_op_varchar BINDING (VARCHAR2)
RETURN VARCHAR2
USING rawtovar;
--6 创建索引类型
--PTTEST.odc_op_varchar(VARCHAR2)
CREATE OR REPLACE INDEXTYPE DBC_INDEX_VAR
FOR
odc_op_varchar(VARCHAR2)
USING power_idxtype_im
WITH LOCAL RANGE PARTITION;
--7 创建辅助视图
create or replace view v_ttt as
select pid,
persionid,
odc_op_varchar(rpersionid) as rpersionid,
name,
odc_op_varchar(rname) as rname,
balance
from ttt;
--8 创建相关扩展索引(DomainIndex)
drop index ODC_IDX_VRPERION;
drop index ODC_IDX_VRNAME;
create index ODC_IDX_VRPERION on ttt(rpersionid) indextype is DBC_INDEX_VAR;
create index ODC_IDX_VRNAME on ttt(rname) indextype is DBC_INDEX_VAR;
--9 查看相关语句的执行计划,并执行
-- 索引验证SQL语句
select *from v_ttt where rpersionid='430268198905018260' and rname = '李';
select *from v_ttt where rpersionid like '430000200404124%';
select *from v_ttt where rname='吕生兰';
select *from v_ttt where rnamelike'吕%';
--10 环境清理
-- 删除中间的索引及类型
drop index ODC_IDX_VRPERION force;
drop index ODC_IDX_VRname force;
--删除索引类型
drop INDEXTYPE DBC_INDEX_VAR force;
drop type power_idxtype_im force;
--函数索引需要手动增删除