2015-08-20 8 views
9

Le prime e le seconde istruzioni "put_line" nel blocco PL/SQL sottostante avranno esito positivo, ma l'ultimo fallisce. Perché? Potrebbe essere un bug?Perché l'ultima istruzione PL/SQL non funziona utilizzando 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; 
/

L'errore è:

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: 

Qualche idea?

+0

Come sembra che abbia qualcosa a che fare con il primo carattere nella variabile. Getta se il primo carattere è un "" – SomeJavaGuy

+0

Dai un'occhiata alla fonte di dbms_assert. –

+0

Si sente come un comportamento bacato. – sstan

risposta

1

non si può dire che il motivo per cui questo sta accadendo, ma si può provare, come di seguito per gestire questa situazione:

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

O puoi provare quanto segue: x: = '' 'Test'; dbms_output.put_line ('x è:' || x || ', enquoted x is:' || replace (dbms_assert.enquote_literal (sostituisci (x, '' '', '' '' '')), '' '', '' '') ); –

+0

continua a ricevere lo stesso errore, dopo aver usato il codice in risposta e utilizzando x: = '' 'Test'; –

+0

Ho appena modificato la risposta, eseguo di nuovo quel blocco plsql e poi controllo, non sto ottenendo alcun errore qui. –

1

di essere indicata https://avoidsqlinjection.wordpress.com/category/5-filtering-input-with-dbms_assert/ che When using ENQUOTE_LITERAL, remember to escape single quotes in the input. ma non ha spiegato molto bene.

Su 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. 

questa domanda è buon esempio che ENQUOTE_LITERAL non qoute stringhe che sono già quoted.But qualunque menzionati sopra ci limita solo per ciò che è ENQUOTE_LITERAL.So soluzione per questo. Come @Vinish Kapoor fa un trucco nella sua risposta che puoi vedere. Quindi, in caso di limitazioni, possiamo convertire la stringa in un altro modello e sostituirla alla normalità. è possibile utilizzare sotto anche

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

o questa

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

Allucinante iniziali e finali singoli qoutes stanno causando problemi possiamo conver in # o ~ e dopo enquote_literal ha fatto il suo lavoro li possiamo sostituire torna a singoli qoutes.

+0

Cosa succede se la stringa contiene già caratteri # o ~? – RGO