5

को हटाने के लिए सुरक्षित है, तो मैं यह जांचने में सक्षम होना चाहता हूं कि SQL सर्वर 2008 में किसी तालिका से पंक्ति को हटाने से यह विफल हो जाएगा कि इसे हटाने के प्रयास किए बिना विदेशी कुंजी उल्लंघन की विफलता हो जाएगी।जांचें कि क्या एक पंक्ति

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

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

मैं डेटा तक पहुंच के लिए इकाई ढांचे का उपयोग कर रहा हूं।

उत्तर

2

यह जांचने का कोई तेज़ और आसान तरीका नहीं है। आप शायद information_schema का उपयोग करके कुछ गतिशील बना सकते हैं, लेकिन निस्संदेह यह बदसूरत और बहुत तेज़ नहीं होगा।

पूर्ण सर्वोत्तम विकल्प कस्टम कोड की कुछ पंक्तियां हैं जो प्रति स्थान सत्यापित करने के लिए होती हैं।

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

1

मैंने पूर्व अनुप्रयोगों में इस तरह की चीज की है। मैंने TryDelete() जैसे कुछ नाम का एक फ़ंक्शन बनाया है। विधि के अंदर, मैंने वांछित पंक्ति को हटाने का प्रयास किया। अगर मुझे एफके अपवाद मिला, तो मैंने इसे पकड़ा और झूठ लौटा दिया। किसी भी मामले में, सही या गलत, मैंने लेनदेन में हटा दिया और फिर इसे वापस घुमाया।

2

जब आप पूछते हैं, तो बच्चे की तालिका में बाएं जॉइन करें। बटन को दिखाया जाना चाहिए या नहीं, यह तय करने के लिए CanDelete गणना मूल्य का उपयोग करें। यदि आप प्रति मूल पंक्ति में 1 से अधिक बाल पंक्ति हैं तो COUNT ने डुप्लिकेट हटा दिए हैं।

SELECT 
    Col1, Col2, Col3, ..., 
    CASE C.Existence WHEN 0 THEN 1 ELSE 0 END AS CanDelete 
FROM 
    ParentTable P 
    LEFT JOIN 
    (
    SELECT COUNT(*) AS Existence, FKColumn 
    FROM Childtable GROUP BY FKColumn 
    ) C ON P.FKColumn = C.FKColumn 
WHERE 
    P.Col = ... 

एक और तरीका हो सकता है

SIGN(C.Existence) AS HasChildRows 
+0

शानदार विचार! लेकिन, वह वस्तुओं में डेटा लोड करने के लिए EntityFramework का उपयोग कर रहा है ... – veljkoz

+0

क्या ईएफ के साथ ऐसा करने का कोई तरीका नहीं है? (शायद एक दृश्य मारा?) –

+0

@veljkoz, @ जेफ शाश्वत: क्षमा करें, कोई विचार नहीं। जैसा कि आपने उल्लेख किया है, आप इसे एक दृश्य में लपेट सकते हैं। – gbn

1

आप अपने इकाई एक विधि है कि जाँच करेगा अगर संदर्भित वस्तुओं मौजूद का एक आंशिक वर्ग में जोड़ सकते हैं।

उदाहरण के लिए, मान लें कि आपके पास Entity1 है जिसमें Entity2 का संग्रह है।

  • ENTITY1 के लिए सच वापसी अगर ENTITY1 ENTITY2
  • में किसी भी आइटम ENTITY2 वापसी संरचना के लिए है ENTITY1
  • के लिए एक संदर्भ है या नहीं: मूल रूप से, इकाई के प्रत्येक आंशिक वर्गों में आप एक संपत्ति IsReferenced कि होगा लिखते हैं

आप अनुमान लगा रहे हैं, आप सुनिश्चित करें कि आप में हमेशा से संदर्भित मान शामिल करने की आवश्यकता होगी अपने लाएं, या, वर्किंग अगर आप संदर्भ से जुड़ी रहे हैं, आप IsReferenced में .Load() इस्तेमाल कर सकते हैं की जाँच से पहले संस्थाओं को लाने के लिए । यह एक उपरि है, यह सिर्फ तभी निर्भर करता है जब आप इसके लिए 'भुगतान' करने के इच्छुक हैं।

फिर, आप उस तत्व संपत्ति के आधार पर 'हटाएं' बटन को दिखा/छुपा सकते हैं, जहां भी हर बार चेक दोहराने से परहेज करते हैं।

0

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

आप किसी लेन-देन है कि वापस बाद में लुढ़का हुआ है अंदर एक वास्तविक delting कोशिश कर सकते हैं या तो है, लेकिन यह भी अगर आप व्यापक हटाता साथ विन्यस्त contraint किया है काम करेंगे ...

एक और तरीका है से सभी contraints निकालने की जाएगी sysobjects तालिका, और सत्यापित करें कि प्रत्येक तालिका में कोई रिकॉर्ड नहीं है। लेकिन इसके लिए कुछ गतिशील एसक्यूएल की आवश्यकता होगी, जो काफी गन्दा हो सकता है।

0

यदि आप डेटाबेस स्तर पर हैं तो मैं उन सभी तालिकाओं में शामिल होगा जहां एक संघर्ष मौजूद हो सकता है।

कोई भी रिकॉर्ड जो वापस लौटाया जा सकता है जिसका अर्थ है कि शेष सेट हो सकता है।

0

मानते हैं कि डेटाबेस का उपयोग कई उपयोगकर्ताओं द्वारा किया जाता है (जो विशाल बहुमत हैं) - "जांच" के बीच अवसर की एक खिड़की होने जा रही है, और संभवतः उपयोगकर्ता पंक्ति को हटाने का निर्णय लेता है, जिसके दौरान कोई और कुछ ऐसी गतिविधि कर सकता है जो परीक्षण के परिणाम को अस्वीकार करता है।

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

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

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