我有一个接受多个参数的存储过程(即pName,pHeight,pTeam)
我有这样的查询:
sqlQuery VARCHAR2(6000); TestCursor T_CURSOR; sqlQuery := 'SELECT ID,Name,Height,Team FROM MyTable WHERE ID IS NOT NULL '; -- Build the query based on the parameters passed. IF pName IS NOT NULL sqlQuery := sqlQuery || 'AND Name LIKE :pName '; END IF; IF pHeight IS > 0 sqlQuery := sqlQuery || 'AND Height = :pHeight '; END IF; IF pTeam IS NOT NULL sqlQuery := sqlQuery || 'AND Team LIKE :pTeam '; END IF; OPEN TestCursor FOR sqlQuery USING pName,pTeam;
如果我执行传递所有参数的过程,它将正常运行.
但是如果我只传递了一个或两个参数,那么程序错误就出来了:
ORA-01006: bind variable does not exist
如何根据参数值的使用位置有选择地将变量与参数绑定?例如,如果只传递了pName,那么我只会执行查询:
OPEN TestCursor FOR sqlQuery USING pName;
或者如果pName和pTeam都通过了,那么:
OPEN TestCursor FOR sqlQuery USING pName,pTeam;
编辑:
我实际上可以使用以下内容:
– 根据传递的参数构建查询.
如果pName不是NULL
sqlQuery:= sqlQuery || ‘和名字一样”’|| pName || ”’;
万一;
IF pHeight IS > 0 sqlQuery := sqlQuery || 'AND Height = pHeight '; END IF; IF pTeam IS NOT NULL sqlQuery := sqlQuery || 'AND Team LIKE ''' || pTeam || ''' '; END IF; OPEN TestCursor FOR sqlQuery;
但这非常容易受到sql注入攻击……
这并不是非常优雅,但它意味着你总是可以提供所有三个绑定变量,即使它们中的一些是null.如果需要,您只需添加额外的WHERE子句.
(我试图格式化动态sql以使其更具可读性,您可以将其作为一个长字符串提供).
FUNCTION myFunc ( pName IN VARCHAR2,pHeight IN VARCHAR2,pTeam IN VARCHAR2 ) RETURN T_CURSOR IS -- Local Variables sqlQuery VARCHAR2(6000); TestCursor T_CURSOR; BEGIN -- Build sql query sqlQuery := 'WITH t_binds '|| ' AS (SELECT :v_name AS bv_name,'|| ' :v_height AS bv_height,'|| ' :v_team AS bv_team '|| ' FROM dual) '|| ' SELECT id,'|| ' name,'|| ' height,'|| ' team '|| ' FROM MyTable,'|| ' t_binds '|| ' WHERE id IS NOT NULL'; -- Build the query WHERE clause based on the parameters passed. IF pName IS NOT NULL THEN sqlQuery := sqlQuery || ' AND Name LIKE bv_name '; END IF; IF pHeight > 0 THEN sqlQuery := sqlQuery || ' AND Height = bv_height '; END IF; IF pTeam IS NOT NULL THEN sqlQuery := sqlQuery || ' AND Team LIKE bv_team '; END IF; OPEN TestCursor FOR sqlQuery USING pName,pTeam; -- Return the cursor RETURN TestCursor; END myFunc;
我不是在具有数据库访问权限的工作站前,所以我无法测试该功能,但它应该关闭(请原谅任何语法错误,这是漫长的一天!)
希望能帮助到你…