2015-08-20 5 views
9

Pierwsza i druga instrukcja "put_line" w poniższym bloku PL/SQL zakończy się pomyślnie, ale ostatnia zakończy się niepowodzeniem. Czemu? Czy to może być błąd?Dlaczego ostatnie polecenie PL/SQL nie działa przy użyciu komendy dbms_assert.enquote_literal?

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; 
/

Błąd jest:

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: 

Każdy pomysł?

+0

Jak się wydaje, ma to coś wspólnego z pierwszym znakiem w zmiennej. Rzuca, jeśli pierwszy znak to '' ' – SomeJavaGuy

+0

Zobacz źródło katalogu dbms_assert. –

+0

Czuje się jak błędne zachowanie. – sstan

Odpowiedz

1

nie można powiedzieć, że dlaczego tak się dzieje, ale można spróbować, jak poniżej obsłużyć to:

set serveroutput on; 
declare 
    x varchar2(100); 
begin 
    x := 'Test'''; 
    dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '''''')), ''' ', '''')); 

    x := 'Te''st'; 
    dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '''''')), ''' ', '''')); 

    x := '''Test'; 

    dbms_output.put_line('x is: ' || x || ', enquoted x is: ' 
    || replace(dbms_assert.enquote_literal(replace(x, '''', ' ''''')), ''' ', '''') 
); 
end; 
/

x is: Test', enquoted x is: 'Test''' 
x is: Te'st, enquoted x is: 'Te''st' 
x is: 'Test, enquoted x is: '''Test' 
PL/SQL procedure successfully completed. 
+0

LUB możesz spróbować następujących rzeczy: x: = '' 'Test'; dbms_output.put_line ('x to:' || x || ', z enquoted x to:' || replace (dbms_assert.enquote_literal (zamień (x, '' '', '' '' '')), '' '', '' '') ); –

+0

wciąż otrzymuję ten sam błąd, po użyciu kodu w odpowiedzi i użyciu x: = '' 'Test'; –

+0

Właśnie zredagowałem odpowiedź jeszcze raz, uruchom ponownie ten blok plsql, a następnie sprawdź, że nie otrzymuję tutaj żadnego błędu. –

1

jest ona wymieniona na https://avoidsqlinjection.wordpress.com/category/5-filtering-input-with-dbms_assert/ tym When using ENQUOTE_LITERAL, remember to escape single quotes in the input. ale nie wyjaśniono bardzo dobrze.

Na docs oracle 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. 

To pytanie jest dobrym przykładem, że ENQUOTE_LITERAL nie qoute sznurki, które już są quoted.But cokolwiek wyżej wymienionych tylko ogranicza nas do ENQUOTE_LITERAL.So co jest rozwiązanie tego problemu. Jak @Vinish Kapoor robi lewę w swojej odpowiedzi, którą widzisz. Tak więc w przypadku ograniczeń możemy zamienić napis na inny wzór i zamienić go na normalny. można skorzystać z poniższego także

dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '#')), '#', '''')); 

czy ten

dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '~')), '~', '''')); 

beacuse początkowe i końcowe pojedynczych qoutes są przyczyną problemu możemy CONVER je # lub ~ a po enquote_literal wykonał swoją pracę możemy je zastąpić z powrotem do pojedynczych pytań.

+0

Co jeśli łańcuch zawiera już znaki # lub ~? – RGO

Powiązane problemy