场景:应用的前台传入一个字符串,而且此字符串具有指定的分隔符,并且长度不定,根据传入的字符串查询对应的结果。
1.使用动态SQL解决
将字符串拆分(例如Java的split函数),然后拼凑到SQL语句中。
缺点:WHERE子句中IN列表中元素的个数必须 <= 1000;列表的数目不确定,无法使用绑定变量,影响效率。
解决:首要考虑就是解决列表长度问题和效率问题,效率问题中首要考虑绑定变量的问题,其次是cardinality对执行计划的影响。
-
--1. 使用静态SQL
-
SET SERVEROUTPUT ON
-
-
DECLARE
-
v_condition VARCHAR2(100);
-
v_sql VARCHAR2(1000);
-
v_count NUMBER(10);
-
BEGIN
-
v_condition := \'\'\'XY\'\'\' || \', \' || \'\'\'YZ\'\'\';
-
dbms_output.put_line(v_condition);
-
--静态SQL
-
SELECT COUNT(*) INTO v_count FROM t WHERE object_name IN (v_condition);
-
dbms_output.put_line(\'static sql:\' || v_count);
-
-
--动态SQL
-
v_sql := \'SELECT COUNT(*) FROM t WHERE object_name IN (\' || v_condition || \')\';
-
dbms_output.put_line(v_sql);
-
EXECUTE IMMEDIATE v_sql INTO v_count;
-
dbms_output.put_line(\'dynamic sql:\' || v_count);
-
END;
-
/
-
-
-
\'XY\', \'YZ\'
-
static sql:0
-
SELECT COUNT(*) FROM t WHERE object_name IN (\'XY\', \'YZ\')
-
dynamic sql:2
-
--结论:打印出来的为动态拼凑的SQL, 而执行的是静态SQL
-
-
--本章要执行的语句
-
SELECT COUNT(*) FROM t WHERE object_name IN (\'XY\', \'YZ\');
-
COUNT(*)
-
----------
-
-
2
-
--实际执行的语句.
-
SELECT COUNT(*) FROM t WHERE object_name IN (\'\'\'XY\'\', \'\'YZ\'\'\');
使用动态SQL,可以得出正确的结果,但会拼凑很多常量,而且数目不定,会导致无法使用绑定变量而影响效率。
并且IN列表中元素个数要< 1000。实际开发不推荐。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17013648/viewspace-1070846/
,如需转载,请注明出处,否则将追究法律责任。