下面的PL / SQL块中的第一个和第二个“put_line”语句将成功,但最后一个语句失败。为什么?这可能是个错误吗?
declare
x varchar2(100);
begin
x := 'Test''';
dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || dbms_assert.enquote_literal(replace(x, '''', '''''')));
x := 'Te''st';
dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || dbms_assert.enquote_literal(replace(x, '''', '''''')));
x := '''Test';
dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || dbms_assert.enquote_literal(replace(x, '''', '''''')));
end;
/
错误是:
Error report:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SYS.DBMS_ASSERT", line 317
ORA-06512: at "SYS.DBMS_ASSERT", line 381
ORA-06512: at line 11
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause:
*Action:
有什么想法吗?
答案 0 :(得分:1)
不能告诉你为什么会发生这种情况,但你可以尝试如下处理:
Test
答案 1 :(得分:1)
提到了
https://avoidsqlinjection.wordpress.com/category/5-filtering-input-with-dbms_assert/
那When using ENQUOTE_LITERAL, remember to escape single quotes in the input.
但没有得到很好的解释。
关于oracle docs http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_assert.htm#ARPLS65379
Usage Notes
Verify that all single quotes except leading and trailing characters are paired with adjacent single quotes.
No additional quotes are added if the name was already in quotes.
这个问题是一个很好的例子,ENQUOTE_LITERAL不会对已经引用过的字符串进行排序。但是上面提到的只是限制我们ENQUOTE_LITERAL.So这是什么解决方案。正如@Vinish Kapoor在他的回答中做了一个你可以看到的技巧。因此,在有限制的情况下,我们可以将字符串转换为其他模式并将其替换回正常状态。你也可以在下面使用
dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '#')), '#', ''''));
或者这个
dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '~')), '~', ''''));
由于导致问题我们可以将它们转换为#或〜并且在enquote_literal完成其工作之后我们可以将它们替换回单个qoutes。