2009-04-10 14 views
6

मेरे पास मेरी एमएस एसक्यूएल सर्वर 2005 तालिका में प्राथमिक कुंजी वाला एक टेबल है। मैं इसे अक्षम करना चाहता हूं। अब मुझे त्रुटि मिलती है:प्राथमिक कुंजी बाधा प्रोग्रामेटिक रूप से अक्षम कैसे करें?

प्राथमिक कुंजी बाधा 'पीके_नाम' का उल्लंघन। ऑब्जेक्ट 'dbo.Table' में डुप्लिकेट कुंजी सम्मिलित नहीं कर सकता।

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

क्वेरी मैं निष्पादित करना चाहता हूं जबकि प्राथमिक कुंजी बाधा अक्षम है जटिल है और प्राथमिक कुंजी कॉलम में मान बदलती है। इस क्वेरी के कुछ बिंदुओं में यह स्थिति को हिट करता है जब मेरे पास प्राथमिक कुंजी कॉलम में डुप्लिकेट मान होते हैं। लेकिन मेरी पूछताछ के अंत में मेरे पास सभी मूल्य अद्वितीय हैं।

मुझे इस बाधा के बारे में बहुत कुछ पता नहीं है क्योंकि मैं इस तालिका के डिजाइनर नहीं हूं। मेरे पास इसका नाम है, लेकिन अब मैं क्लस्टर नहीं हुआ हूं और इसी तरह (इस कॉलम की कॉन्फ़िगरेशन क्या है)।

+0

पी मूल्यों को बदलने से विश्राम के लिए बनायीं गयी निष्पादित: यह वास्तव में वास्तव में अजीब लगता है! टेबल के बीच संबंधों को लागू करने के लिए उपयोग किए जाने वाले मानों को आप कैसे बदल सकते हैं? क्या आप सुनिश्चित हैं कि जिस समाधान को आप विस्तारित करने का प्रयास कर रहे हैं वह आपकी समस्या का समाधान है? –

+0

मेरे पास इस पीके पर कोई संबंध नहीं है। मुझे पता है कि अजीब लगता है और शायद ऐसा है, लेकिन यह वह समाधान है जिसे मुझे इस जगह में आवेदन करने की आवश्यकता है। –

+1

यदि डुप्लिकेट हैं, तो यह अब प्राथमिक कुंजी नहीं है, तो इसे कभी भी क्यों जोड़ें? क्या आपने एक समेकित प्राथमिक कुंजी माना है जो आपको बाधा रखने की अनुमति देगा? –

उत्तर

5

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

मुझे यकीन नहीं है कि आपको प्राथमिक कुंजी बाधा क्यों छोड़नी है, लेकिन मैं इसे अन्य उम्मीदवार कुंजियों में से किसी एक के साथ बदलने के बिना ऐसा करने पर विचार करता हूं, जिसकी जांच की जानी चाहिए।

+0

आपने बताया है कि यह समाधान खराब क्यों है, इसलिए मैंने आपके उत्तर को उचित रूप से चिह्नित करने का निर्णय लिया। और इसके अलावा मैंने समाधान के बारे में एक और सवाल पूछा है जो इस काम को सही तरीके से करेगा: –

+3

एक कारण यह है कि आप बाधा को छोड़ना चाहते हैं यदि आप बहुत सारे डेटा में टेबल परिवर्तन कर रहे हैं। हमने हाल ही में 8 मिल रिकॉर्ड के साथ एक टेबल में दो नए कॉलम जोड़े। कॉलम जोड़ने में 23 घंटे लग गए। अगर हम बाधाओं को छोड़ देते हैं, तो इसमें 12 मिनट लगते हैं। बेशक, हम ऑफलाइन अपग्रेड के बारे में बात कर रहे हैं। यदि यह एक ऑनलाइन अपग्रेड है, तो बाधाओं को छोड़ना खतरनाक होगा। – dsum

13
ALTER TABLE mytable DROP CONSTRAINT PK_Name 

यह पुन: सक्षम करने के लिए:

ALTER TABLE mytable ADD CONSTRAINT PK_Name PRIMARY KEY /* CLUSTERED */ (pk_column) 

टिप्पणी हटाएं CLUSTERED अगर आप अपने PRIMARY KEY गुच्छेदार रूप में (यानी तालिका पंक्तियों खुद को आदेश दिया जा रहा है)

पता लगाने के लिए अगर PRIMARY KEY क्लस्टर है चाहता हूँ नहीं, मुद्दा:

EXEC sp_help 'mytable' 

और 6th परिणाम देखें।

+0

यह बाधा को दूर करने लगता है।इसे कैसे पुनर्स्थापित करें? –

+0

समस्या यह है कि मुझे नहीं पता कि मेरे पास प्राथमिक कुंजी क्लस्टर है या नहीं। तो मैं इसे इस तरह से बहाल नहीं कर सकता। –

+1

प्राथमिक कुंजी डिफ़ॉल्ट रूप से क्लस्टर किया जाता है - इसलिए यदि आपने इसे नहीं बदला है, तो यह क्लस्टर है। –

0

पीकेईई बाधा का उल्लंघन न करें। आईएमएचओ यह सबसे अच्छा समाधान है, आप एक पीकेईई के पुनर्निर्माण की लागत से बचेंगे और यदि आप नहीं कर सकते (शेष डुप्लिकेट)?

या

स्कीमा पढ़ें पता है कि कैसे PKEY बाधा के पुनर्निर्माण के लिए तो previouly तैनात समाधान का उपयोग करें।

+0

पुनर्निर्माण PKEY मेरे लिए कोई लागत नहीं है, इसलिए मैं इस दिशा में जाना चाहूंगा। –

0

SELECT आपकी पूरी तालिका अस्थायी तालिका में, बेहतर होने पर उड़ान पर परिवर्तन करने और फिर इसे कॉपी करने का बेहतर विचार हो सकता है। और यदि आप फ्लाई पर बदल नहीं सकते हैं, तो अस्थायी तालिका पर प्राथमिक कुंजी के रूप में एक सरल पूर्णांक पंक्ति अनुक्रमणिका जोड़ने के लिए बहुत आसान है।

2

यह जानने के लिए कि प्राथमिक कुंजी क्या है (मान लें कि आपकी तालिका डीबीओ है।टी 1):

select si.name as name, 
(case when (si.status & 16) > 0 then 1 else 0 end) as isclust, 
si.keycnt as keycnt, 
si.indid as indid 
from sysindexes si 
left join sysobjects so on so.id = si.id 
where si.indid > 0 
and si.indid < 255 
and so.xtype <> 'S' 
and so.id = OBJECT_ID('dbo.T1') 
and (si.status & 2048) > 0 

यह आपको कुछ दे देंगे:

 
name         isclust  keycnt indid 
--------------------------------------------------------------- 
PK_T1          1   2  1 

यहाँ आप अपने प्राथमिक कुंजी का नाम (PK_T1 है), चाहे वह क्लस्टर है या नहीं, उस में फ़ील्ड की संख्या (2) और इंडेक्स आईडी (आपको बाद में इसकी आवश्यकता होगी)।

select INDEX_COL('dbo.T1', 1, 1) --returns Field1 
select INDEX_COL('dbo.T1', 1, 2) --returns Field2 

यह आपको सूचकांक से दो क्षेत्रों के नाम दे देंगे:

अगला निम्नलिखित चलाते हैं। पहला पैरामीटर आपका टेबल नाम है, दूसरा इंडेक्स आईडी पहले प्राप्त होता है और तीसरा एक 1 से keycnt (पिछले चरण पर लौटाया जाता है) से लूप होता है।

यह जानकारी आपको इस प्रकार प्राथमिक कुंजी फिर से संगठित करने में सक्षम होना चाहिए करने के बाद:

ALTER TABLE dbo.T1 ADD CONSTRAINT PK_T1 PRIMARY KEY CLUSTERED (Field1, Field2) 

अपडेट: यह पार्स करने sp_help परिणाम उल्लेख earlier के रूप में के रूप में सही नहीं हो सकता है (यदि आप सॉर्ट क्रम और filegroup याद करेंगे) , लेकिन प्रोग्रामेटिक रूप से आसान है।

0

नीचे (आप इस क्रिया को करने db_owner होना चाहिए) मेरे लिए काम किया

एक चर

DECLARE @PK_CONST_NAME AS varchar(100)<br> 
SET @PK_CONST_NAME = (SELECT NAME FROM SYS.KEY_CONSTRAINTS WHERE OBJECT_NAME(PARENT_OBJECT_ID) = '[TABLENAME]') 

को मेज पर contraints हो और आवंटित करने के लिए एक चर --Declare - प्रश्नों स्टोर करने के लिए चर

SET @DropAlterQuery = ''<br> 
SET @RecreateAlterQuery = '' 

- contruct क्वेरी

SET @DropAlterQuery = CONCAT('ALTER TABLE [TABLENAME] DROP CONSTRAINT ',@PK_CONST_NAME) 

- क्वेरी contraints

EXEC(@DropAlterQuery) 

droping के लिए बनायीं गयी निष्पादित - परिवर्तन स्तंभ का आकार (अब इस बयान से काम करता है के रूप में contraints गिरा दिया जाता है)

ALTER TABLE [TABLENAME] 
ALTER COLUMN BATCH_ID VARCHAR(200) NOT NULL 

- contruct क्वेरी

SET @RecreateAlterQuery = CONCAT(CONCAT('ALTER TABLE [TABLENAME] ADD CONSTRAINT ',@PK_CONST_NAME), ' PRIMARY KEY (<<PRIMARY KEY COLUMN1>>, <<PRIMARY KEY COLUMN2>>, <<PRIMARY KEY COLUMN2>>... So on)') 

- क्वेरी गिरा contraints

EXEC(@RecreateAlterQuery) 
संबंधित मुद्दे