2010-03-29 15 views
6

मेरे पास एक संग्रहीत प्रक्रिया है जो बहुत सारे डिलीट कर रही है। सैकड़ों हजारों रिकॉर्ड। यह आवेदन से चलने योग्य नहीं है, लेकिन फिर भी, मुझे चिंतित है कि मेरे ग्राहकों में से एक गलती से इसे चलाता है (मुझे उनकी "जिज्ञासा" के कारण पहले समस्याएं थीं: डीक्या संग्रहीत प्रक्रिया निष्पादन के लिए "क्या आप निश्चित हैं"? :)

हां। ऐसे बैकअप और सामान हैं, लेकिन मैं सोच रहा था .... उन्हें डराने के लिए नहीं ... क्या उपयोगकर्ता से पूछने का कोई तरीका है "क्या आप निश्चित हैं?" इसे निष्पादित करने से पहले? :) धन्यवाद

+10

आप अपनी संग्रहीत प्रोसेस के लिए अनुमति क्यों सेट नहीं करते हैं? इस तरह, केवल अधिकृत उपयोगकर्ता ही इसे चला सकते हैं। –

+0

@ द एलिट जेंटलमैन: मैं यह नहीं कह रहा हूं कि अधिकृत उपयोगकर्ता कभी-कभी मशीनों की बजाय मनुष्यों की तरह महसूस करना चाहेंगे। यह विशेष मामला दिखाता है कि कुछ डेवलपर्स उपयोगकर्ताओं को केवल प्राणियों के रूप में नहीं समझते हैं। :) –

उत्तर

7

मुझे लगता है कि आप एक पैरामीटर है कि एक विशेष स्ट्रिंग की आवश्यकता है "पुष्टि" कहा जाता है हो सकता है (उदा, "मैं जानता हूँ कि मैं क्या कर रहा हूँ"), पास होने के लिए अगर यह सेट नहीं है, या गलत तरीके से सेट किया गया है, मुख्य कोड निष्पादित किए बिना प्रक्रिया से वापस लौटें। बिल्कुल वही नहीं जो आप चाहते थे, लेकिन यह एक विकल्प है।

जैसे - (अपरीक्षित और शायद भयानक वाक्य रचना)

CREATE PROCEDURE dbo.mySproc (
@Confirmation Varchar(100) 
) AS 
BEGIN 
    if(@Confirmation <> 'I know what I am doing') 
    BEGIN 
     return; 
    END 
    DELETE from table_name where condition 
END 
+0

यह काम कर सकता है, लेकिन मुझे लगता है कि यह जल्दी से "प्रतिलिपि बनाएं और पेस्ट करें और पैरामीटर को अनदेखा करें" –

+4

सहमत हो गया है, लेकिन अगर उन्हें सीधे स्पोक तक पहुंच हो तो उन्हें कुछ भी छोड़ने से रोकने के लिए कुछ भी नहीं है। पूरी चीज के आसपास उचित पहुंच/निष्पादन सुरक्षा जोड़ने के लिए बेहतर है। – ZombieSheep

+0

+1 मैं पूरी तरह से सहमत हूं, यह अनुशासन का विषय है –

6

संक्षेप में, नहीं।

सिद्धांत यह है कि अनुमति रखने वाले किसी भी व्यक्ति को संग्रहीत प्रक्रिया को चलाने और चलाने में सक्षम होने की अनुमति दी जानी चाहिए। अनुमतियों को प्रतिबंधित करना बेहतर होगा ताकि अतिरिक्त जिज्ञासा वाले लोगों को इसे चलाने की अनुमति न हो।

अन्य, कम सुरक्षित, विकल्प के लिए एक पूर्व निर्धारित गुप्त एक पैरामीटर के रूप में पारित करने की आवश्यकता है कि आवश्यकता के लिए हो सकता है - निश्चित रूप से वे सिर्फ स्क्रिप्ट संग्रहीत प्रक्रिया बंद गुप्त हालांकि खोजने के लिए कर सकते हैं ...

बेशक, दूसरा बिंदु होगा: यदि यह कॉल करने योग्य नहीं है, तो इसे क्यों शामिल करें? आखिरकार, जब आप व्यवस्थापक प्रकार के कार्यों को करने के लिए आते हैं, तो आप अपनी फाइल पर सुरक्षित रख सकते हैं कि आप अपनी मशीन पर सुरक्षित रख सकते हैं

1

आप @UserKnowsWhatTheyAreDoing नामक एक बिट इनपुट का उपयोग कर सकते हैं और यह देखने के लिए जांच सकते हैं कि यह है या नहीं निष्पादन से पहले सच है। यदि यह गलत है, तो एक दोस्ताना संदेश प्रिंट करें और प्रक्रिया

2

पर आप @reallyReallyReallyDelete पैरामीटर जोड़ सकते हैं जो सुरक्षा उपाय के रूप में कार्य करेगा: यदि यह YesYesYes पर सेट है तो वास्तव में लेनदेन को प्रतिबद्ध करेगा।

1

प्रक्रिया को 'Yes I know what I'm doing' जैसे किसी विशिष्ट मान के साथ तर्क की आवश्यकता हो सकती है। या यह एक पंक्ति को एक समान तालिका और एक हालिया टाइमस्टैम्प के साथ एक विशेष तालिका की तलाश कर सकता है।

3

एक बहु-स्तरीय आयामी दृष्टिकोण का उपयोग करें:

1) नियंत्रण सुरक्षा पर अमल, जैसे:

GRANT EXECUTE ON [dbo].[yourProcedure] TO [userxyz] 

2) एक बहुत वर्णनात्मक/डरावना प्रक्रिया नाम का उपयोग, जैसे

CREATE PROCEDURE Will_Delete_All_Your_Data ... 

3) संग्रहित प्रक्रिया की शुरुआत में एक बड़ी आंख पकड़ने वाली टिप्पणी डालें

--NOTE, will delete all of your data-- 
--NOTE, will delete all of your data-- 
--NOTE, will delete all of your data-- 
--NOTE, will delete all of your data-- 
--NOTE, will delete all of your data-- 

4) बनाने के एक अस्पष्ट विशेष एक्सेस कोड में उपयोगकर्ता पास:

CREATE PROCEDURE Will_Delete_All_Your_Data 
(
    @SpecialCode varchar(30) 
) 

IF @SpecialCode!=CHAR(83)+CHAR(112)+CHAR(101)+CHAR(99)+CHAR(105)+CHAR(97)+CHAR(108)+CHAR(67)+CHAR(111)+CHAR(100)+CHAR(101) 
BEGIN 
    RETURN 999 
END 
... 

FYI करें, विशेष कोड 'SpecialCode' हो या वापसी 999 मारा जाता है चाहिए।

0

क्या आपको वास्तव में उन्हें डीबी से हटाना होगा? अगर मैं अतिरिक्त जगह पर खर्च कर सकता हूं तो मैं अपनी टेबलों में एक 'हटाया गया' ध्वज और अंतिम अद्यतन कॉलम डालूंगा। इस तरह यदि रिकॉर्ड कम से कम गलती से हटा दिया जाता है तो मैं आमतौर पर इसे ट्रैक कर सकता हूं और इसे आसानी से बहाल कर सकता हूं। सिर्फ एक विचार।

1

यहां एक और दृष्टिकोण है, जो मुझे लगता है कि विशेष मामले के लिए उपयुक्त है जब किसी एप्लिकेशन द्वारा किसी एप्लिकेशन से सीधे प्रक्रिया को कॉल किया जाना है।

मुझे कहना होगा कि यह अधिकतर सुझावों के मुकाबले डेवलपर के लिए अधिक (शायद, असमान रूप से) उपयोगकर्ता के लिए कम परेशानी का प्रस्ताव है। आप तय करते हैं कि यह आपके लिए उपयुक्त है या नहीं।

वैसे भी, यहां जाता है।

सबसे पहले, आप महत्वपूर्ण प्रक्रियाओं पर कॉल पंजीकृत करने के लिए एक विशेष तालिका, CriticalCalls बनाते हैं।

SPID int, 
ProcName sysname, 
CallTime datetime 

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

तो हर महत्वपूर्ण प्रक्रिया के शुरू हिस्सा इस तर्क होगा:

IF NOT EXISTS (
    SELECT * 
    FROM CriticalCalls 
    WHERE SPID = @@SPID AND ProcName = @ThisProcName 
    AND GETDATE() - CallTime BETWEEN @LowerCallTimeLimit AND @UpperCallTimeLimit 
    /* the actual test for the time interval might be somewhat different */ 
) BEGIN 
    ... /* upsert CriticalCalls with the current time stamp */ 
    PRINT 'To proceed, please call this procedure again within...'; 
    RETURN; 
END; 

DELETE FROM CriticalCalls WHERE SPID = @@SPID AND ProcName = @ThisProcName; 

... /* proceed with your critical task */ 

वास्तव में, मुझे लगता है, यह सबसे अच्छा होगा CriticalCalls के साथ सभी जोड़तोड़ के लिए एक समर्पित सपा (नीचे CheckCriticalCalls नाम) का उपयोग करने के सहित, सभी आवश्यक संशोधन। CheckCriticalCalls को जांचने की प्रक्रिया का नाम प्राप्त होगा और यह दिखाएगा कि निर्दिष्ट प्रक्रिया को अपना असली ऑपरेशन करना चाहिए या नहीं।

तो यह इस तरह नहीं बल्कि दिख सकता है:

EXECUTE @result = CheckCriticalCalls 'ThisProcedureName'; 
IF @result = -1 BEGIN 
    PRINT 'Call me again'; 
    RETURN; 
END; 

... /* go on with the task */ 

अंतराल की निचली सीमा की स्थापना के पीछे विचार यह एक महत्वपूर्ण प्रक्रिया दो बार स्वचालित रूप से बुला, दो समान EXECUTE... लाइनों को क्रियान्वित करते हुए IE से उपयोगकर्ता को रोकने के लिए केवल है एक बैच में ऊपरी सीमा, ज़ाहिर है, 1) यह सुनिश्चित करना है कि उपयोगकर्ता महत्वपूर्ण संचालन करने के लिए अपने हालिया इरादे की पुष्टि करता है; 2) निष्पादन को रोकें यदि CriticalCalls में मौजूदा रिकॉर्ड वास्तव में एक ही एसपीआईडी ​​के साथ पिछले सत्र से वहां छोड़ा गया है।

तो, मूल रूप से, 1-2 सेकंड से आधा मिनट का अंतराल मेरे लिए काफी प्राकृतिक प्रतीत होता है। आप इसके बजाय अलग-अलग आंकड़े चुन सकते हैं।

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