在我的存储过程中,我有一个动态查询 - where子句中的条件数因输入参数而异。
in params - x, y, z
searchsql := 'select select1, select2, select3 from tableA where 1 = 1 and ';
if(x is not null) then
searchSql := searchSql || PKG_COMMON.GET_SQL_BINDTXTFLD(x,'select1','a');
-- above package will return AND upper(select1) like upper(:a)
cursorParams := cursorParams || ':' || x || ',';
end if;
if(y is not null) then
searchSql := searchSql || PKG_COMMON.GET_SQL_BINDTXTFLD(y,'select2','b');
-- above package will return AND upper(select2) like upper(:b)
cursorParams := cursorParams || ':' || y || ',';
end if;
--I am trimming the last comma of the cursor param
SELECT SUBSTR(cursorParams, 1, INSTR(cursorParams , ',', -1)-1)
INTO cursorParams FROM dual;
open resultCursor for searchSql using cursorParams
现在,我有上面的游标需要使用传递的params打开,但是在这种情况下,params的数量取决于sql是如何形成的。所以我使用cursorParams变量动态形成绑定变量
但是这些值没有绑定,只能设置为第一个参数
如何正确绑定,我已经尝试过执行立即选项
答案 0 :(得分:1)
出了什么问题:
select select1, select2, select3
from tableA
where (:a is null
OR upper(select1) like upper(:a))
and (:b is null
OR upper(select2) like upper(:b))
and (:c is null
OR upper(select3) like upper(:c));
(假设您已禁用绑定查看)
答案 1 :(得分:0)
http://docs.oracle.com/cloud/latest/db121/ARPLS/d_sql.htm
Native Dynamic SQL是DBMS_SQL的替代方法,它允许您将动态SQL语句直接放入PL / SQL块中。在大多数情况下,Native Dynamic SQL比DBMS_SQL更易于使用和执行。但是,Native Dynamic SQL本身有一些限制:
不支持所谓的方法4(对于输入或输出数量未知的动态SQL语句)
答案 2 :(得分:0)
以下是使用DBMS_SQL动态构建和绑定的一个简单示例。
DECLARE
i_owner all_objects.owner%TYPE := 'SYS';
i_object_name all_objects.object_name%TYPE := 'DUAL';
i_object_type all_objects.object_type%TYPE := NULL;
v_statement VARCHAR2(4000);
v_cursor BINARY_INTEGER := dbms_sql.open_cursor;
v_rows BINARY_INTEGER;
v_result SYS_REFCURSOR;
v_owner all_objects.owner%TYPE;
v_object_name all_objects.object_name%TYPE;
v_object_type all_objects.object_type%TYPE;
BEGIN
v_statement := 'select owner, object_name, object_type from all_objects where 1 = 1';
IF i_owner IS NOT NULL THEN
v_statement := v_statement ||
q'[ and owner like upper(:owner) || '%']';
END IF;
IF i_object_name IS NOT NULL THEN
v_statement := v_statement ||
q'[ and object_name like upper(:object_name) || '%']';
END IF;
IF i_object_type IS NOT NULL THEN
v_statement := v_statement ||
q'[ and object_type like upper(:object_type) || '%']';
END IF;
dbms_output.put_line(v_statement);
dbms_sql.parse(c => v_cursor,
STATEMENT => v_statement,
language_flag => dbms_sql.native);
IF i_owner IS NOT NULL THEN
dbms_sql.bind_variable(c => v_cursor,
NAME => 'owner',
VALUE => i_owner);
END IF;
IF i_object_name IS NOT NULL THEN
dbms_sql.bind_variable(c => v_cursor,
NAME => 'object_name',
VALUE => i_object_name);
END IF;
IF i_object_type IS NOT NULL THEN
dbms_sql.bind_variable(c => v_cursor,
NAME => 'object_type',
VALUE => i_object_type);
END IF;
v_rows := dbms_sql.execute(c => v_cursor);
IF v_rows >= 0 THEN
v_result := dbms_sql.to_refcursor(cursor_number => v_cursor);
LOOP
FETCH v_result
INTO v_owner,
v_object_name,
v_object_type;
EXIT WHEN v_result%NOTFOUND;
dbms_output.put_line(v_owner || ' ' || v_object_name || ' ' ||
v_object_type);
END LOOP;
END IF;
END;
/