如何确定系统中存在没有绑定变量的情况,可以使用ASKTOM网站提供的remove_constants()函数查看共享池中SQL运行情况
create or replace function remove_constants(p_query in varchar2) return varchar2
is
l_query long;
l_char varchar2(1);
l_in_quotes boolean default FALSE;
begin
for i in 1.. length(p_query)
loop
l_char := substr(p_query,i,1);
if (l_char = '''' and l_in_quotes)
then
l_in_quotes := FALSE;
elsif (l_char = '''' and NOT l_in_quotes)
then
l_in_quotes := TRUE;
l_query := l_query || '''#';
end if;
if (NOT l_in_quotes) then
l_query := l_query || l_char;
end if;
end loop;
l_query := translate(l_query,'0123456789','@@@@@@@@@@');
for i in 0 .. 8 loop
l_query := replace(l_query,lpad('@',10-i,'@'),'@');
l_query := replace(l_query,lpad(' ',10-i,' '),' ');
end loop;
return upper(l_query);
end;
如何使用?
--建表T用于测试
create table t (x int primary key);
insert into t select rownum from user_objects;
commit;
--不使用绑定变量测试
begin
for i in 1..1000 loop
execute immediate 'select * from t where x=' || i;
end loop;
end;
--建表T1用于保存共享池中的SQL
create table t1 as select sql_text from v$sqlarea;
--保存经过函数remove_constants()处理过的SQL
alter table t1 add sql_text_wo_constants varchar2(1000);
update t1 set sql_text_wo_constants = remove_constants(sql_text);
--经过函数remove_constants()处理后,SQL中的谓词被替换成@
select sql_text_wo_constants,count(*) from t1 group by sql_text_wo_constants having count(*) > 10;--数字可以自己改成其他
这样就知道哪些SQL没有绑定变量了。