sql中带有IN的子查询绑定变量实现方式

尘封飞扬 2009-09-14

在sql中经常会带有IN的子查询,如whereidin(1,2,3)。如果这样的语句在数据库中出现,将引起数据库的大量硬解析与共享池SQL碎片,

下面介绍种将这些Inlist给绑定起来:

1;首先针对数据类型和字符类型的绑定创建两个类型。

createorreplacetypenumtabletypeastableofnumber;

createorreplacetypevartabletypeastableofvarchar2(1000);

创建两个函数,分别来解析Inlist中的串

2:

CREATEORREPLACEFUNCTIONstr2numList(p_stringINvarchar2)RETURNnumtabletype

AS

v_strLONGDEFAULTp_string||',';

v_nNUMBER;

v_datanumtabletype:=numtabletype();

BEGIN

LOOP

v_n:=to_number(instr(v_str,','));

EXITWHEN(nvl(v_n,0)=0);

v_data.extend;

v_data(v_data.count):=ltrim(rtrim(substr(v_str,1,v_n-1)));

v_str:=substr(v_str,v_n+1);

ENDLOOP;

RETURNv_data;

END;

CREATEORREPLACEFUNCTIONstr2varList(p_stringINvarchar2)RETURNvartabletype

AS

v_strLONGDEFAULTp_string||',';

v_nvarchar2(2000);

v_datavartabletype:=vartabletype();

BEGIN

LOOP

v_n:=to_number(instr(v_str,','));

EXITWHEN(nvl(v_n,0)=0);

v_data.extend;

v_data(v_data.count):=ltrim(rtrim(substr(v_str,1,v_n-1)));

v_str:=substr(v_str,v_n+1);

ENDLOOP;

RETURNv_data;

END;

3:使用方式

添加Hint为了稳定执行计划

SELECT/*+ordereduser_nl(a,b)*/b.*FROMTABLE(str2numList(:bind0))a,ACCOUNTbWHEREb.id=a.column_value;

SELECT/*+ordereduser_nl(a,b)*/b.*FROMTABLE(str2numList('1,2,3'))a,ACCOUNTbWHEREb.id=a.column_value;

SELECT/*+leading(a)*/*FROMACCOUNTWHEREIDIN(SELECT*FROMTABLE(str2numList(:bind1))a);

SELECT/*+leading(a)*/*FROMACCOUNTWHEREID

参考资料:构件oracle高可用环境

相关推荐