2009-06-25 11 views
22

मुझे प्रारंभिक मान के साथ एक एमएस एसक्यूएल 2005 डेटाबेस में एक नया कॉलम जोड़ने की जरूरत है। हालांकि, मैं इस कॉलम पर स्वचालित रूप से डिफ़ॉल्ट बाधा नहीं बनाना चाहता हूं। उस बिंदु पर जब मैं कॉलम जोड़ता हूं तो डिफ़ॉल्ट/प्रारंभिक मान सही होता है, लेकिन यह समय के साथ बदल सकता है। इसलिए, तालिका में भविष्य तक पहुंच को डिफ़ॉल्ट को स्वीकार करने के बजाय एक मान निर्दिष्ट करना होगा।प्रारंभिक (लेकिन डिफ़ॉल्ट नहीं) मान के साथ एक नया कॉलम जोड़ने का सबसे अच्छा तरीका?

सबसे अच्छा मैं के साथ आ सकता है:

ALTER TABLE tbl ADD col INTEGER NULL 
UPDATE tbl SET col = 1 
ALTER TABLE tbl ALTER COLUMN col INTEGER NOT NULL 

यह बड़ा सा टेबल (100,000 1,000,000 रिकॉर्ड) के लिए एक सा अक्षम लगता है।

मैंने डिफ़ॉल्ट रूप से कॉलम जोड़ने और फिर डिफ़ॉल्ट बाधा को हटाने के साथ प्रयोग किया है। हालांकि, मुझे नहीं पता कि डिफ़ॉल्ट बाधा का नाम क्या है और सिसोबजेक्ट तक नहीं पहुंच पाएगा और डेटाबेस विशिष्ट ज्ञान में डालेगा।

कृपया, एक बेहतर तरीका होना चाहिए।

उत्तर

16

में कर सकते हैं मैं ALTER TABLE tbl ADD col INTEGER CONSTRAINT tempname DEFAULT 1 पहले चाहते ,, और बाद (लेन-देन के भीतर शायद) ड्रॉप कोई स्पष्ट नाम बाधा।

+1

+1। --- @ एलेक्स: मुझे यकीन नहीं है कि कोई एक ट्रैशक्शन के भीतर डीडीएल कर सकता है। --- @ एड्रियन: क्या आप वास्तव में अक्षम होने की परवाह करते हैं? आप इसे हर दिन नहीं कर रहे हैं, है ना? आम तौर पर मैं स्पष्टता के लिए वर्णन करने के तरीके का उपयोग करता हूं। – van

+0

@van, मैं इस संबंध में SqlServer'05 की सीमाओं के 100% निश्चित नहीं हूं - PostgreSQL आपको लेन-देन तालिका को बदलने देता है (कम से कम लेनदेन के स्पष्ट BEGIN और COMMIT के साथ)। यह जांचने के लिए कि क्या एमएस भी करता है, SELECT @@ TRANCOUNT आपको बताएगा (मुझे यह स्पष्ट रूप से दस्तावेज़ों में वर्तनी नहीं मिल सकती है)। –

+0

@van & @Alex एमएस एसक्यूएल सर्वर लेनदेन के भीतर डीडीएल करता है। –

1

आप एक डालने ट्रिगर

+0

ठीक वही है जो मुझे लगता है। बीटीडब्ल्यू वाई क्या आप इसे बाधा के रूप में नहीं करना चाहते हैं –

+0

प्रश्न मौजूदा पंक्तियों वाली तालिका में कॉलम जोड़ने के लिए है। एक ट्रिगर जोड़ना केवल नई पंक्तियों को प्रभावित करेगा। क्या मैं कुछ भूल रहा हूँ? –

+0

मुझे लगता है कि मैंने इस सवाल को गलत समझा। जब आप कहते हैं कि आप प्रारंभिक मान के साथ एक कॉलम जोड़ना चाहते हैं, तो क्या आपका मतलब है कि आप सभी मौजूदा पंक्तियों को अपडेट करने के बिना यह मान रखना चाहते हैं? इस मामले में, आप दो कॉलम जोड़ सकते हैं। एक एक शून्य कॉलम है और दूसरा एक गणना कॉलम है। यदि अन्य कॉलम शून्य है तो गणना कॉलम डिफ़ॉल्ट मान वापस कर देगा, अन्यथा यह अन्य कॉलम वापस कर देगा। यह बहुत जटिलता आगे बढ़ रही है। मैं ऐसा करूंगा जैसा आपने अपने उदाहरण में किया था। –

0

यदि आप तालिका बनाते समय डिफ़ॉल्ट बाधा डालते हैं, तो आप नहीं जान पाएंगे कि इसे क्या कहा जाता है। हालांकि, अगर आप अल्टर टेबल के साथ बाधा डालते हैं, तो आपको बाधा का नाम देना होगा। इस मामले में, आप तालिका ड्रॉप कन्स्ट्रेंट को बदलने में सक्षम होंगे (यह टी-एसक्यूएल पर लागू होता है, अन्य डेटाबेस के बारे में निश्चित नहीं है।)

हालांकि, आपको नल कॉलम के साथ तालिका बनाने की आवश्यकता होगी, वैकल्पिक तालिका को जोड़ने के लिए बाधा, कॉलम न्यूल, और अंत में ड्रॉप कंसस्ट्रेंट बनाते हैं।

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

मुझे लगता है कि जिस तरह से आप वर्णन करते हैं, वास्तव में, सबसे कुशल और सुरुचिपूर्ण समाधान हो सकता है।

11

एक डिफ़ॉल्ट के साथ स्तंभ जोड़ने के लिए और फिर डिफ़ॉल्ट हटाते हैं, तो आप डिफ़ॉल्ट नाम कर सकते हैं:

ALTER TABLE tbl ADD col INTEGER NOT NULL CONSTRAINT tbl_temp_default DEFAULT 1 
ALTER TABLE tbl drop constraint tbl_temp_default 

यह मान 1 में भरा है, लेकिन एक डिफ़ॉल्ट के बिना मेज छोड़ देता है। SQL सर्वर 2008 का उपयोग करके, मैंने यह और आपका कोड alter update alter चलाया और 100,000 छोटी पंक्तियों की तालिका पर कोई ध्यान देने योग्य अंतर नहीं देखा। एसएसएमएस मुझे तालिका तालिका में बदलाव के लिए क्वेरी प्लान नहीं दिखाएगा, इसलिए मैं दो तरीकों के बीच उपयोग किए गए संसाधनों की तुलना करने में सक्षम नहीं था।