त्रुटि से बचने के लिए टेबल संरचना को ठीक करना: डुप्लिकेट कुंजी मान अद्वितीय अवरोध का उल्लंघन करता है


15

मेरे पास एक तालिका है जो इस प्रकार बनाई गई है:

--
-- Table: #__content
--
CREATE TABLE "jos_content" (
  "id" serial NOT NULL,
  "asset_id" bigint DEFAULT 0 NOT NULL,
   ...
  "xreference" varchar(50) DEFAULT '' NOT NULL,
  PRIMARY KEY ("id")
);

बाद में कुछ पंक्तियों को आईडी निर्दिष्ट किया जाता है:

INSERT INTO "jos_content" VALUES (1,36,'About',...)

बाद के बिंदु पर कुछ रिकॉर्ड बिना आईडी के डाले जाते हैं और वे त्रुटि के साथ विफल हो जाते हैं Error: duplicate key value violates unique constraint:।

जाहिरा तौर पर आईडी को एक अनुक्रम के रूप में परिभाषित किया गया है:

यहाँ छवि विवरण दर्ज करें

प्रत्येक विफल सम्मिलित क्रम में सूचक को तब तक बढ़ाता है जब तक कि यह मूल्य में वृद्धि नहीं करता है जो अब मौजूद नहीं है और क्वेरी सफल होती है।

SELECT nextval('jos_content_id_seq'::regclass)

तालिका की परिभाषा में क्या गलत है? इसे ठीक करने का स्मार्ट तरीका क्या है?


PostgreSQL में, यदि आप सभी लोअरकेस हैं, तो आपको कॉलम और टेबल नामों को उद्धृत करने की आवश्यकता नहीं है।
रॉड्रिगो

जवाबों:


19

आपकी तालिका परिभाषा में कुछ भी गलत नहीं है।
(टोपी को छोड़कर मैं jos_content_idगैर-विवरणात्मक कॉलम नाम के बजाय उपयोग या कुछ और कर सकता हूं id
और मैं शायद इसके बजाय उपयोगtextvarchar(50) करूंगा ।

आपका INSERTकथन समस्या है।

आपके idकॉलम को इस रूप में परिभाषित करने के लिए serial, आपको मैन्युअल मानों को सम्मिलित नहीं करना चाहिए id। वे संबंधित अनुक्रम से अगले मूल्य से टकरा सकते हैं।

लक्ष्य स्तंभों की एक स्पष्ट सूची प्रदान करें (जो कि निरंतर INSERTकथनों के लिए हमेशा एक अच्छा विचार है ) और धारावाहिक स्तंभों को पूरी तरह से छोड़ दें

INSERT INTO jos_content(asset_id, some_column, ...)
VALUES (36,'About',...);

यदि आपको तुरंत उत्पन्न कॉलम (एस) के मूल्य की आवश्यकता है, तो RETURNINGक्लॉज का उपयोग करें :

INSERT ...
RETURNING id;  -- possibly more

SO पर इस संबंधित उत्तर में अधिक जानकारी:

आप में मैन्युअल प्रविष्टियों है, तो serialकॉलम कि हो सकता है संघर्ष के बाद, वर्तमान अधिकतम करने के लिए अपने अनुक्रम सेट idकरने के लिए ठीक इस एक बार :

SELECT setval('jos_content_id_seq', max(id))
FROM   jos_content;

jos_content_id_seqउस अनुक्रम के लिए डिफ़ॉल्ट नाम कहां है jos_content.id, जिसके स्वामित्व में आप पहले से ही कॉलम डिफ़ॉल्ट में पाए गए हैं। xhzt8_content_id_seqअपने मामले में लगता है ;


अद्यतन: एक समान मुद्दा SO पर पॉप अप हुआ और मैं एक नया समाधान लेकर आया:


क्या विचर (50) की तुलना में पाठ धीमा नहीं है?
रॉड्रिगो

2
@ रोड्रिगो: पोस्टग्रेज में नहीं। अधिक स्पष्टीकरण के लिए ऊपर एक लिंक है: dba.stackexchange.com/a/21496/3684 । या इधर। dba.stackexchange.com/a/89433/3684
एरविन ब्रान्डस्टेट्टर

यहां अंतिम परीक्षण < depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text > ने मुझे आश्वस्त किया कि अधिकांश क्षेत्रों के लिए varchar (n) तेज है जहां आकार में प्रतिबंध सुविधाजनक है (लोग) नाम, ईमेल, पते, प्रजातियों के नाम, आदि)। यदि आप लंबाई की जांच नहीं करेंगे, तो पाठ तेज (या समान) है, ऐसा लगता है।
रॉड्रिगो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.