我在动态sql中有一个更新语句,如下所示:
varDynQuery := 'UPDATE TABLE SET B0 = ' || A0;
IF(A1 IS NOT NULL) THEN
varDynQuery := varDynQuery || ', B1 = ' || A1;
END IF;
IF(A2 IS NOT NULL) THEN
varDynQuery := varDynQuery || ', B2 = ' || A2;
END IF;
我想将其更改为使用绑定变量来防止SQL注入
varDynQuery := 'UPDATE TABLE SET B0 = :A0';
IF(A1 IS NOT NULL) THEN
varDynQuery := varDynQuery || ', B1 = :A1';
END IF;
IF(A2 IS NOT NULL) THEN
varDynQuery := varDynQuery || ', B2 = :A2';
END IF;
EXECUTE IMMEDIATE varDynQuery USING
A0, A1, A2;
但是,由于A1和A2并不总是存在,因此在过程运行期间可能会导致错误。
有没有办法塑造SQL语句,以便可以成功绑定所有变量而不更新那些需要排除的变量?
注意:想避免使用合并。
答案 0 :(得分:3)
只需确保包含所有绑定变量,例如:
varDynQuery := 'UPDATE TABLE SET B0 = :A0,
B1 = NVL(:A1,B1),
B2 = NVL(:A2,B2)';
EXECUTE IMMEDIATE varDynQuery USING
A0, A1, A2;
这种方法的优点是只需要解析一个查询,这意味着共享池上的负载更少。
唯一的缺点是,如果您有任何特定于列的触发器,即使它们没有被更改,它们也会触发B1和B2。
如果这是一个问题,您需要为四种更新方案中的每一种使用不同的执行立即(例如B0; B0 + B1; B0 + B2; B0 + B1 + B2)
答案 1 :(得分:0)
另一个解决方案就是这个:
varDynQuery := 'UPDATE TABLE SET B0 = :A0';
IF(A1 IS NOT NULL) THEN
varDynQuery := varDynQuery || ', B1 = :A1';
END IF;
IF(A2 IS NOT NULL) THEN
varDynQuery := varDynQuery || ', B2 = :A2';
END IF;
IF A1 IS NOT NULL THEN
IF A2 IS NOT NULL THEN
EXECUTE IMMEDIATE varDynQuery USING A0, A1, A2;
ELSE
EXECUTE IMMEDIATE varDynQuery USING A0, A1;
END IF;
ELSE
IF A2 IS NOT NULL THEN
EXECUTE IMMEDIATE varDynQuery USING A0, A2;
ELSE
EXECUTE IMMEDIATE varDynQuery USING A0;
END IF;
END IF;
但是,如果你有更多的变量而不仅仅是2-3,那么你的代码就会变得很拥挤。