2008-12-16 23 views
9

जैसा कि विषय से पता चलता है कि मैं तालिका नामों को .NET का उपयोग कर पैरामीटर के रूप में पास करने में सक्षम होना चाहता हूं (इससे कोई फर्क नहीं पड़ता कि वास्तव में कौन सी भाषा) और SQL सर्वर।.NET/SQL में पैरामीटर तालिका का नाम?

मुझे पता है कि मूल्यों के लिए यह कैसे करें, उदा। पैरामीटर को इंगित करने के लिए क्वेरी में command.Parameters.AddWithValue("whatever", whatever)@whatever का उपयोग कर। बात यह है कि मैं ऐसी परिस्थिति में हूं जहां मैं क्वेरी के अन्य हिस्सों जैसे कॉलम और टेबल नामों के साथ ऐसा करने में सक्षम होना चाहता हूं।

यह एक आदर्श स्थिति नहीं है, लेकिन मुझे इसका उपयोग करना है, यह वास्तव में एसक्यूएल इंजेक्शन के लिए प्रवण नहीं है क्योंकि कोड का उपयोग करने वाला कोई भी व्यक्ति इन तालिका नामों को सेट कर सकता है न कि अंतिम उपयोगकर्ता। हालांकि यह गन्दा है।

तो, क्या मैं संभव पूछ रहा हूं?

संपादित करें: एसक्यूएल इंजेक्शन के बारे में बिंदु स्पष्ट करने के लिए, तालिका के नाम केवल स्थिति के आधार पर स्रोत कोड द्वारा पारित किए जाते हैं। यह डेवलपर है जो इसे निर्दिष्ट करता है। डेवलपर को डेटाबेस परत तक पहुंच होगी, इसलिए मैं जो कारण पूछ रहा हूं वह सुरक्षा के लिए इतना नहीं है बल्कि कोड क्लीनर बनाने के लिए है।

उत्तर

3

मुझे नहीं लगता मैंने कभी भी देखा है कि किसी भी SQL बोली में मैंने यह क्षमता देखी है, लेकिन यह विशेषज्ञता का क्षेत्र नहीं है।

मैं अक्षरों को एजेड, एजी, 0-9, '।', '_' और '' 'में प्रतिबंधित करने का सुझाव दूंगा - और उसके बाद डेटाबेस के लिए उपयुक्त ब्रैकेटिंग जो भी हो (उदाहरण के लिए [] SQL सर्वर के लिए, I विश्वास करो) पूरी चीज को लपेटने के लिए। फिर बस इसे सीधे एसक्यूएल में रखें।

यह पूरी तरह स्पष्ट नहीं है कि इसका मतलब एसक्यूएल इंजेक्शन जोखिम नहीं है - क्या आपका मतलब है कि नाम स्रोत कोड में होंगे और केवल स्रोत कोड में होंगे? यदि ऐसा है, तो मैं सहमत हूं कि चीजों को बेहतर बनाता है। आपको यदि पर ब्रैकेटिंग स्वचालित रूप से करने की आवश्यकता भी नहीं हो सकती है, तो आप अपने डेवलपर्स पर विश्वास करते हैं कि वे क्रेटिन न हों (जानबूझकर या नहीं)।

+0

यूप, सोर्स कोड और केवल सोर्स कोड में। यह इस बात को दोबारा करने के दौरान अद्यतन/सम्मिलित बयान बनाने का आसान काम करना है। – Damien

4

आप किसी अन्य पैरामीटर की तरह पैरामीटर के रूप में तालिका का नाम पास कर सकते हैं। कुंजी यह है कि आपको एक गतिशील एसक्यूएल कथन बनाना है, जो तब आपको विचार करना चाहिए कि इसे अपने ऐप स्तरीय या प्रोसेस में बनाना आसान है या नहीं।

create procedure myProc 

@tableName nvarchar(50) 

as 

sp_executesql N'select * from ' + @tablename 

FYI इस कोड नमूना स्मृति से sp_executesql का उचित वाक्य रचना के लिए बोल पर एक नजर है है।

यह भी एसक्यूएल इंजेक्शन के लिए अत्यधिक स्वीकार्य है जैसा कि आपने संकेत दिया है कि यह आपके लिए कोई मुद्दा नहीं है, लेकिन इसे पढ़ने वाला कोई भी व्यक्ति इस तरह के प्रश्नों को उत्पन्न करने के लिए उपयोगकर्ता से इनपुट स्वीकार करने से बहुत सावधान रहना चाहिए।

+0

'+ @tablename से * चुनें। तब parametrised हो? (वीबी.Net कोड का उपयोग, संग्रहित प्रक्रियाओं नहीं)। – Damien

+0

यदि आप vb.net में क्वेरी बनाते हैं तो कोई @table को पैरामीकृत करने की आवश्यकता नहीं होगी। आपका वीबी कोड sqlString = "select * से" + tableName जैसा दिखता है। फिर आप कमांड ऑब्जेक्ट के रूप में sqlString निष्पादित करेंगे। (सेट कमांड टाइप को टेक्स्ट) – JoshBerke

3

एसक्यूएल क्वेरी पैरामीटर केवल एक शाब्दिक मूल्य की जगह ले सकते हैं। आप तालिका नाम, कॉलम नाम, मानों की सूची, या अन्य SQL वाक्यविन्यास के लिए पैरामीटर का उपयोग नहीं कर सकते हैं। डेटाबेस के सभी ब्रांडों में यह मानक एसक्यूएल व्यवहार है।

तालिका नाम गतिशील बनाने का एकमात्र तरीका यह है कि आप उस स्ट्रिंग को एक कथन के रूप में तैयार करने से पहले एक चर को अपने SQL क्वेरी में विभाजित करना है।

बीटीडब्ल्यू, अगर आपको लगता है कि यह एसक्यूएल इंजेक्शन के लिए जोखिम नहीं है तो आप खुद को बेवकूफ़ बना रहे हैं। यदि आप टेबल नाम को गतिशील रूप से क्वेरी में विभाजित करते हैं, तो आपको तालिका नाम के आस-पास delimited identifiers का उपयोग करने की आवश्यकता है, जैसे आप किसी चर से शाब्दिक स्ट्रिंग अक्षर के चारों ओर उद्धरणों का उपयोग करेंगे।

5

आप तालिका नाम को सीधे पैरामीटर नहीं कर सकते हैं।आप इसे sp_ExecuteSQL के माध्यम से अप्रत्यक्ष रूप से कर सकते हैं, लेकिन आप सी # में (पैरामीटरकृत) TSQL भी बना सकते हैं (तालिका-नाम को जोड़ना, लेकिन अन्य मानों को नहीं) और इसे कमांड के रूप में भेज दिया। आपको वही सुरक्षा मॉडल मिलता है (यानी आपको स्पष्ट चयन आदि की आवश्यकता है, और यह मानते हुए कि यह हस्ताक्षरित नहीं है आदि)।

इसके अलावा - तालिका के नाम को सफेद सूची में रखना सुनिश्चित करें।

2

यह विचार कि यह एसक्यूएल इंजेक्शन के लिए प्रवण नहीं है, गुमराह है। यह कम फ्रंट एंड उपयोगकर्ताओं से एसक्यूएल इंजेक्शन के लिए प्रवण हो सकता है, लेकिन यह अभी भी एसक्यूएल इंजेक्शन के लिए बहुत अधिक प्रवण है। डेटाबेस पर अधिकतर हमले कंपनी के अंदर से आते हैं, अंतिम उपयोगकर्ताओं से नहीं।

कर्मचारी शिकायत हो सकती है, वे बेईमान हो सकता है, वे असंतुष्ट हो सकता है या वे सिर्फ इतना उज्जवल नहीं हो सकता है और लगता है कि यह यह जो कुछ भी उन्हें लगता है लिए किया जाना चाहिए है क्या करने के लिए बाईपास सुरक्षा के लिए ठीक है हो सकता है डेटाबेस।

+0

मैं यह कहने जा रहा था, बस इसके बजाय मतदान किया। जब तक कि पैरामीटर हार्डकोडेड पसंद न हो, यह करना एक बुरा विचार है। –

+3

ठीक है, कंपनी के लोगों को या तो पहुंच नहीं होगी। यह केवल कॉलिंग विधि है जो फ़ील्ड और टेबल नाम निर्दिष्ट करने में सक्षम होगी। असल में, जो भी व्यवसाय तर्क तक पहुंच प्राप्त करता है उसे डेटा एक्सेस कोड तक पहुंच होगी, वैसे भी, – Damien

0

कृपया उपयोगकर्ता Vimvq1987 द्वारा इस पोस्ट जवाब देखें: MySqlParameter as TableName

अनिवार्य रूप से आप पहली बार स्कीमा, जिसमें तालिका नाम एक पैरामिट्रीकृत फैशन में प्रयोग किया जाता है के खिलाफ तालिका नाम की जाँच करें। फिर यदि सब ठीक है, तो तालिका का नाम कानूनी है।

दूसरे शब्दों में बयान मूल विचार है:

SELECT table_name 
    FROM information_schema.tables 
    WHERE table_schema = 'databasename' 
    AND table_name = @table; 

    cmd.Parameters.AddWithValue("@table",TableName); 

इस तालिका नाम, अपने मुख्य क्वेरी के साथ आगे बढ़ो साथ ठीक देता है, तो ...

0

मैं बस की जाँच करेगा select OBJECT_ID(@tablename) विचार को रोकने के लिए है इंजेक्शन आपको पता है कि इसे टेबल नाम होना चाहिए, अगर यह एक संख्या देता है तो मैं वास्तविक क्वेरी चलाता हूं,

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