2015-08-20 3 views
9

नीचे पीएल/एसक्यूएल ब्लॉक में एफआईआर और दूसरा "put_line" कथन सफल होगा लेकिन आखिरी व्यक्ति विफल हो जाएगा। क्यूं कर? क्या यह एक बग हो सकता है?अंतिम पीएल/एसक्यूएल कथन 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; 
/

त्रुटि है:

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

ऐसा लगता है कि यह चर के पहले वर्ण के साथ कुछ करने के लिए है। यह पहला फेंक देता है अगर पहला अक्षर '' – SomeJavaGuy

+0

dbms_assert के स्रोत पर नज़र डालें। –

+0

छोटी गाड़ी व्यवहार की तरह लगता है। – sstan

उत्तर

1

आप बता सकते हैं नहीं है कि क्यों यह हो रहा है, लेकिन आप इस संभाल करने के लिए नीचे के रूप में की कोशिश कर सकते हैं:

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

या आप निम्न का प्रयास कर सकते हैं: x: = '' 'test'; dbms_output.put_line ('x है:' || x || ', enquoted x है:' || प्रतिस्थापित करें (dbms_assert.enquote_literal (प्रतिस्थापित करें (x, '' '', '' '' '' ')), '' '', '' '' ') ); –

+0

अभी भी वही त्रुटि प्राप्त कर रहा है, उत्तर में अपने कोड का उपयोग करने और x: = '' 'test' का उपयोग करने के बाद; –

+0

मैंने अभी जवाब दोबारा संपादित किया है, फिर से plsql ब्लॉक चलाएं और फिर जांचें, मुझे यहां कोई त्रुटि नहीं मिल रही है। –

1

यह https://avoidsqlinjection.wordpress.com/category/5-filtering-input-with-dbms_assert/ कि When using ENQUOTE_LITERAL, remember to escape single quotes in the input. पर उल्लेख किया गया है, लेकिन बहुत अच्छी तरह से समझाया नहीं।

ओरेकल डॉक्स पर 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 तार जो पहले से ही कर रहे हैं quoted.But जो केवल ENQUOTE_LITERAL.So इस के लिए समाधान है क्या हमें सीमित करता है जैसा कि ऊपर उल्लेख qoute नहीं होगा। जैसा कि @ विनीश कपूर अपने जवाब में एक चाल है कि आप देख सकते हैं। तो सीमाओं के मामले में हम स्ट्रिंग को किसी अन्य पैटर्न में परिवर्तित कर सकते हैं और उसे सामान्य पर बदल सकते हैं। यह एक

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

प्रमुख और एकल qoutes समस्या हम उन्हें # या में बातचीत कर सकते हैं उत्पन्न कर रहे हैं अनुगामी वजह से आप भी

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

नीचे का उपयोग करें या ~ और enquote_literal के बाद अपने काम किया है हम उन्हें बदल सकते हैं कर सकते हैं एकल qoutes पर वापस।

+0

क्या होगा यदि स्ट्रिंग में पहले से # या ~ अक्षर हैं? – RGO

संबंधित मुद्दे