使用绑定变量进行动态SQL更新

时间:2015-03-26 07:41:36

标签: sql oracle

我在动态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语句,以便可以成功绑定所有变量而不更新那些需要排除的变量?

注意:想避免使用合并。

2 个答案:

答案 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,那么你的代码就会变得很拥挤。