क्या पोस्टग्रेज़ के पास ALTER TABLE foo ADD CONSTRAINT bar ...
कहने का कोई तरीका है जो बाधा पहले से मौजूद है, तो यह आदेश को अनदेखा कर देगा, ताकि यह कोई त्रुटि न उठाए?पोस्टग्रेज़: यदि यह पहले से मौजूद नहीं है तो
उत्तर
यह मदद कर सकता है, हालांकि यह एक गंदा हैक का एक सा हो सकता है: तो फिर
create or replace function create_constraint_if_not_exists (
t_name text, c_name text, constraint_sql text
)
returns void AS
$$
begin
-- Look for our constraint
if not exists (select constraint_name
from information_schema.constraint_column_usage
where table_name = t_name and constraint_name = c_name) then
execute constraint_sql;
end if;
end;
$$ language 'plpgsql'
फोन के साथ:
SELECT create_constraint_if_not_exists(
'foo',
'bar',
'ALTER TABLE foo ADD CONSTRAINT bar CHECK (foobies < 100);')
अपडेट किया गया:
प्रति Webmut's answer के रूप में सुझाव नीचे:
ALTER TABLE foo DROP CONSTRAINT IF EXISTS bar;
ALTER TABLE foo ADD CONSTRAINT bar ...;
कि अपने विकास डेटाबेस में शायद ठीक है, या जहाँ आप जानते हैं आपको लगता है कि एक रखरखाव खिड़की के लिए इस डेटाबेस पर निर्भर क्षुधा को बंद कर सकते हैं।
लेकिन यदि यह एक जीवंत मिशन महत्वपूर्ण 24x7 उत्पादन वातावरण है, तो आप वास्तव में इस तरह की बाधाओं को छोड़ना नहीं चाहते हैं। यहां तक कि कुछ मिलीसेकंड्स के लिए एक छोटी सी खिड़की है जहां आप अब अपनी बाधा को लागू नहीं कर रहे हैं जो ग़लत मूल्यों को फिसलने की अनुमति दे सकता है। उसमें अनपेक्षित परिणाम हो सकते हैं जिससे सड़क पर कुछ बिंदु पर काफी व्यावसायिक लागत आती है।
आप बाधा को खोजने के लिए pg_constraint
मेज पर क्वेरी चला सकते हैं मौजूद है या not.like:
SELECT 1 FROM pg_constraint WHERE conname = 'constraint_name'"
वहाँ है 'ड्रॉप कन्स्ट्रेंट 'के लिए' अगर एक्सस्टिस्ट्स 'विकल्प, लेकिन, AFAIK,' कंसस्ट्रेंट जोड़ें 'के लिए कुछ नहीं। –
बाध्यता नाम एक टेबल के लिए स्थानीय हैं? क्या होता है यदि 'constraint_name' नामक बाधा वाले दो तालिकाओं हैं? – guettli
हां, यदि किसी अन्य तालिका में एक ही बाधा नाम था तो आप झूठी सकारात्मक प्राप्त कर सकते हैं। लेकिन यह अभी भी एक सभ्य समाधान है यदि आप अपने नामकरण के नियंत्रण में 100% हैं। –
पता नहीं क्यों कोड की इतनी सारी लाइनें?
- चयन करें "कॉलम 1", "कॉलम 2", "कॉलम 3", डीबीओ से गिनती (स्टार)। "माईटेबल" ग्रुप "कॉलम 1", "कॉलम 2", "कॉलम 3" हैविंग गिनती (*)> 1;
तालिका डीबीओ को बदलें। "MyTonstraint_Name" मौजूद है "MyTable" ड्रॉप बाधा;
वैकल्पिक तालिका डीबीओ। "मायटेबल" कंसस्ट्रेंट "MyConstraint_Name" अद्वितीय ("कॉलम 1", "कॉलम 3", "कॉलम 2") जोड़ें;
एक संभावित समाधान केवल नई बाधा बनाने से पहले ड्रॉप IF EXISTS का उपयोग करना है।
ALTER TABLE foo DROP CONSTRAINT IF EXISTS bar;
ALTER TABLE foo ADD CONSTRAINT bar ...;
INFORMATION_SCHEMA या कैटलॉग क्वेरी करने के लिए कोशिश कर रहा है की तुलना में आसान लगता है, लेकिन बहुत बड़ा टेबल पर धीमी गति से हो सकता है क्योंकि यह हमेशा बाधा का पुनर्निर्माण करने वाला।
संपादित करें 2015-07-13: केवी ने his answer में बताया कि मेरा समाधान एक छोटी सी खिड़की बनाता है जब बाधा मौजूद नहीं होती है और इसे लागू नहीं किया जा रहा है। हालांकि यह सच है, आप एक लेनदेन में दोनों बयानों को लपेटकर आसानी से ऐसी खिड़की से बच सकते हैं।
डुप्लिकेट ऑब्जेक्ट त्रुटि को पकड़ने के लिए आप अज्ञात डीओ ब्लॉक के अंदर अपवाद हैंडलर का उपयोग कर सकते हैं।
DO $$
BEGIN
BEGIN
ALTER TABLE foo ADD CONSTRAINT bar ... ;
EXCEPTION
WHEN duplicate_object THEN RAISE NOTICE 'Table constraint foo.bar already exists';
END;
END $$;
http://www.postgresql.org/docs/9.4/static/sql-do.htmlhttp://www.postgresql.org/docs/9.4/static/plpgsql-control-structures.html http://www.postgresql.org/docs/9.4/static/errcodes-appendix.html
को 'duplicate_object' को' duplicate_table' (कोड 42P07) में बदलना था। पोस्टग्रेस 9.6 – volvpavl
बनाना कमी तो मैं गिर नहीं करने की सलाह देते कमी केवल तुरंत उन्हें फिर से बनाने के लिए डेटा के बहुत सारे युक्त एक मेज पर एक महंगी आपरेशन किया जा सकता है के तुरंत बाद - आप केवल कि बनाना चाहते हैं एक बार बात
मैं एक गुमनाम कोड ब्लॉक, बहुत माइक Stankavich के लिए इसी तरह का उपयोग कर इस को हल करने के लिए चुना है, लेकिन माइक (जो एक त्रुटि पकड़ता) मैं पहली बार अगर बाधा मौजूद है देखने के लिए जाँच के विपरीत:
DO $$ BEGIN IF NOT EXISTS (SELECT constraint_schema , constraint_name FROM information_schema.check_constraints WHERE constraint_schema = 'myschema' AND constraint_name = 'myconstraintname' ) THEN ALTER TABLE myschema.mytable ADD CONSTRAINT myconstraintname CHECK (column <= 100); END IF; END$$;
- 1. वर्ग - यदि मौजूद नहीं है तो
- 2. यदि रिकॉर्ड मौजूद है, तो
- 3. SqlAlchemy: ऑब्जेक्ट बनाएं यदि पहले से मौजूद नहीं है?
- 4. बनाएँ यदि मौजूद नहीं है
- 5. एक कुकी अगर (और केवल यदि) बनाएं यह पहले से ही मौजूद नहीं है
- 6. SQLite में केवल तालिका बनाएं यदि यह पहले से मौजूद नहीं है
- 7. केवल पायथन में एक मॉड्यूल आयात करें यदि यह पहले से मौजूद नहीं है
- 8. mysql केवल तभी दृश्य बनाएं यदि यह पहले से मौजूद नहीं है
- 9. किसी तालिका में एक कॉलम जोड़ें, यदि यह पहले से मौजूद नहीं है
- 10. चींटी: फ़ाइल युक्त निर्देशिका बनाएं यदि यह पहले से मौजूद नहीं है?
- 11. डालें यदि मौजूद नहीं है तो बस mysql
- 12. डेटाबेस में ऑब्जेक्ट सहेजें यदि यह पहले से मौजूद नहीं है (हाइबरनेट और स्प्रिंग)
- 13. एक्सएसएलटी: यदि टैग मौजूद है, तो टेम्पलेट लागू करें; यदि नहीं, तो स्थिर मान चुनें
- 14. MySQL: कॉलम कैसे जोड़ें यदि यह पहले से मौजूद नहीं है?
- 15. जावास्क्रिप्ट: यदि सरणी मौजूद है, तो जांचें,
- 16. यदि स्थिति मौजूद है तो MySQL ट्रिगर
- 17. यदि यह मौजूद नहीं है तो कोई सरणी में कोई तत्व पुश करें (कोई डुप्लीकेट नहीं)
- 18. यदि कुंजी मौजूद नहीं है तो डिफ़ॉल्ट मान
- 19. यदि बच्चा मौजूद नहीं है तो माता-पिता रिकॉर्ड हटाएं
- 20. नकल File.Move यदि गंतव्य पहले से मौजूद है
- 21. क्या WebClient.DownloadFileAsync फ़ाइल को ओवरराइट करता है यदि यह डिस्क पर पहले से मौजूद है?
- 22. एएनएसआई एसक्यूएल प्रश्न - यदि रिकॉर्ड पहले से मौजूद है तो रिकॉर्ड कैसे डालें या अपडेट करें?
- 23. फ़ाइल पहले से मौजूद नहीं हो सकती है जब फ़ाइल पहले से मौजूद है
- 24. यदि वाईएएमएल मार्कअप भाषा नहीं है, तो यह क्या है?
- 25. PHP fopen() फ़ाइल नहीं बना रहा है अगर यह पहले से मौजूद नहीं है
- 26. jQuery: जांच करें कि मान सरणी में है, यदि ऐसा है, तो हटाएं, यदि नहीं, तो
- 27. फ़ाइल को निकालें यदि यह मौजूद है
- 28. क्या उपयोगकर्ता मॉडल पहले से मौजूद है, तो क्या यह संभव है?
- 29. अगर रजिस्ट्री प्रविष्टि मौजूद है तो ऐसा करें, यदि ऐसा नहीं है, तो
- 30. या तो कोई सूची बनाने के लिए कुशल तरीका, या यदि कोई पहले से मौजूद है तो इसमें शामिल हों?
मुझे लगता है कि आपके पिछले उदाहरण में 'myconstraint' ''bar' होना चाहिए। –
@denis - अच्छी तरह पकड़ा गया। धन्यवाद। – Kev
मैं इस उत्तर को और संशोधित कर दूंगा ताकि निष्पादन कथन 'निष्पादित करें' वैकल्पिक तालिका '|| t_name || 'कंसस्ट्रेंट जोड़ें' || c_name || '' || constraint_sql; 'और फ़ंक्शन को कॉल करना' SELECT create_constraint_if_not_exists ('foo', 'bar', 'चेक (foobies <100);') जैसा दिखता है; '। यह सुनिश्चित करता है कि आप अपनी बाधा एसक्यूएल में तर्कों को गड़बड़ नहीं कर सकते क्योंकि वे मूल पैरामीटर पर आधारित हैं। –