टी एल; डॉ
यहाँ एक संस्करण है जहाँ आपको किसी मान को पढ़ने और उसे स्वयं टाइप करने के लिए मानव की आवश्यकता नहीं है।
CREATE SEQUENCE foo_a_seq OWNED BY foo.a;
SELECT setval('foo_a_seq', coalesce(max(a), 0) + 1, false) FROM foo;
ALTER TABLE foo ALTER COLUMN a SET DEFAULT nextval('foo_a_seq');
एक अन्य विकल्प Functionइस उत्तर के अंत में साझा किए गए पुन: प्रयोज्य को नियोजित करना होगा ।
एक गैर-संवादात्मक समाधान
उदाहरण के लिए, एक लाइव-ईश डीबी को पैच करते हुए, हम में से उन दो लोगों के लिए, जो Sequenceएक गैर-इंटरैक्टिव स्क्रिप्ट द्वारा बनाए जाने की आवश्यकता है, उन दोनों के लिए अन्य दो उत्तरों को जोड़ते हुए।
यही है, जब आप SELECTमैन्युअल रूप से मूल्य नहीं चाहते हैं और बाद के CREATEबयान में खुद को टाइप करते हैं ।
संक्षेप में, आप कर सकते हैं नहीं :
CREATE SEQUENCE foo_a_seq
START WITH ( SELECT max(a) + 1 FROM foo );
... के बाद से START [WITH] खंड CREATE SEQUENCEएक मूल्य की अपेक्षा करता है , उपशम की नहीं।
नोट: एक सामान्य नियम के, सभी गैर-CRUD (लागू होने के रूप में यानी : के अलावा और कुछ INSERT, SELECT,UPDATE , DELETEमें बयान) pgSQL AFAIK।
हालाँकि, setval()करता है! इस प्रकार, निम्नलिखित बिल्कुल ठीक है:
SELECT setval('foo_a_seq', max(a)) FROM foo;
यदि कोई डेटा नहीं है और आप इसके बारे में नहीं जानना चाहते हैं, तो उपयोग करें coalesce() तो डिफ़ॉल्ट मान सेट लिए करें:
SELECT setval('foo_a_seq', coalesce(max(a), 0)) FROM foo;
-- ^ ^ ^
-- defaults to: 0
हालाँकि, वर्तमान अनुक्रम मान सेट करना 0अनाड़ी है, यदि अवैध नहीं है।
के तीन-पैरामीटर रूप का उपयोग करनाsetval करना अधिक उपयुक्त होगा:
-- vvv
SELECT setval('foo_a_seq', coalesce(max(a), 0) + 1, false) FROM foo;
-- ^ ^
-- is_called
के वैकल्पिक तीसरे पैरामीटर की स्थापना setvalकरने के लिएfalsenextval से मूल्य को वापस करने से पहले अनुक्रम को आगे बढ़ाने से रोका जा सकता है , और इस प्रकार:
अगला nextval वास्तव में निर्दिष्ट मान लौटाएगा, और अनुक्रम उन्नति निम्नलिखित के साथ शुरू होगी nextval।
- प्रलेखन में इस प्रविष्टि से
एक असंबंधित नोट पर, आप Sequenceसीधे कॉलम के साथ निर्दिष्ट कर सकते हैं CREATE, आपको इसे बाद में बदलने की आवश्यकता नहीं है:
CREATE SEQUENCE foo_a_seq OWNED BY foo.a;
संक्षेप में:
CREATE SEQUENCE foo_a_seq OWNED BY foo.a;
SELECT setval('foo_a_seq', coalesce(max(a), 0) + 1, false) FROM foo;
ALTER TABLE foo ALTER COLUMN a SET DEFAULT nextval('foo_a_seq');
इसका उपयोग करना Function
वैकल्पिक रूप से, यदि आप कई स्तंभों के लिए ऐसा करने की योजना बना रहे हैं, तो आप वास्तविक उपयोग करने का विकल्प चुन सकते हैं Function।
CREATE OR REPLACE FUNCTION make_into_serial(table_name TEXT, column_name TEXT) RETURNS INTEGER AS $$
DECLARE
start_with INTEGER;
sequence_name TEXT;
BEGIN
sequence_name := table_name || '_' || column_name || '_seq';
EXECUTE 'SELECT coalesce(max(' || column_name || '), 0) + 1 FROM ' || table_name
INTO start_with;
EXECUTE 'CREATE SEQUENCE ' || sequence_name ||
' START WITH ' || start_with ||
' OWNED BY ' || table_name || '.' || column_name;
EXECUTE 'ALTER TABLE ' || table_name || ' ALTER COLUMN ' || column_name ||
' SET DEFAULT nextVal(''' || sequence_name || ''')';
RETURN start_with;
END;
$$ LANGUAGE plpgsql VOLATILE;
इसका इस्तेमाल ऐसे करें:
INSERT INTO foo (data) VALUES ('asdf');
-- ERROR: null value in column "a" violates not-null constraint
SELECT make_into_serial('foo', 'a');
INSERT INTO foo (data) VALUES ('asdf');
-- OK: 1 row(s) affected
SERIALछद्म प्रकार अब विरासत है , जिसे SQL: 2003 में परिभाषित नएGENERATED … AS IDENTITYफ़ीचर द्वारा पोस्टग्रेज 10 और बाद में हटा दिया गया है। स्पष्टीकरण देखें ।