যখন পোস্টগ্রিসের প্রাথমিক কী ক্রমটি সিঙ্কের বাইরে চলে যায় তখন কীভাবে পুনরায় সেট করবেন?


522

আমি এই সমস্যায় পড়েছিলাম যে আমার প্রাথমিক কী ক্রমটি আমার টেবিল সারিগুলির সাথে সুসংগত নয়।

এটি হ'ল আমি যখন একটি নতুন সারিটি sertোকানোর সময় আমি একটি সদৃশ কী ত্রুটি পাই কারণ সিরিয়াল ডেটাটাইপটিতে বর্ণিত ক্রমটি ইতিমধ্যে বিদ্যমান একটি নম্বর প্রদান করে।

দেখে মনে হচ্ছে এটি আমদানি / পুনরুদ্ধারটি যথাযথভাবে ধারাবাহিকতা রক্ষণ না করার কারণে ঘটেছে।


আমি কৌতূহলী .. আপনি পুনরুদ্ধার করার আগে আপনি ডিবি বাদ দিচ্ছেন? আমার এই ঘটনার একটি চমকপ্রদ স্মৃতি আছে, তবে আমি ভুল হতে পারি: পি
আর্থার টমাস

25
পোস্টগ্র্রেএসকিউএল উইকির একটি ফিক্সিং সিকোয়েন্সে একটি পৃষ্ঠা রয়েছে ।
ব্র্যাড কোচ

14
কেবল গুগলিবলিকে সহায়তা করার জন্য, এখানে ফেলে দেওয়া ত্রুটি বার্তাটি হ'ল: "সদৃশ কী মানটি অনন্য প্রতিবন্ধকতা লঙ্ঘন করে ..."
অতিবৃত্তাকার

4
জ্যাঙ্গোতে স্ক্যাল সিকোয়েন্সেন্সেট এটি এভাবে করে: সেটআপ নির্বাচন করুন (pg_get_serial_sequence ("<table_name>", 'id'), coalesce (সর্বাধিক ("আইডি"), 1), সর্বোচ্চ ("আইডি") নাল নয়) FROM "< TABLE_NAME> ";
ব্যবহারকারী

<টেবিলের নাম> এর প্রথম উদাহরণটি কাজ করার জন্য pg_get_serioal_sequence ফাংশনটির জন্য একক উদ্ধৃতিতে আবৃত হওয়া প্রয়োজন: SELECT সেটওয়াল (pg_get_serial_sequence ('<টেবিল_নাম>', 'আইডি'), কোয়েলস (সর্বোচ্চ ("আইডি"), 1) , সর্বাধিক ("আইডি") নাল নয়) "<
table_name

উত্তর:


715
-- Login to psql and run the following

-- What is the result?
SELECT MAX(id) FROM your_table;

-- Then run...
-- This should be higher than the last result.
SELECT nextval('your_table_id_seq');

-- If it's not higher... run this set the sequence last to your highest id. 
-- (wise to run a quick pg_dump first...)

BEGIN;
-- protect against concurrent inserts while you update the counter
LOCK TABLE your_table IN EXCLUSIVE MODE;
-- Update the sequence
SELECT setval('your_table_id_seq', COALESCE((SELECT MAX(id)+1 FROM your_table), 1), false);
COMMIT;

সূত্র - রুবি ফোরাম


12
যে কোনও হারে, 1 থেকে MAX (আইডি) যুক্ত করা আপনার আইডিতে একক সংখ্যার ফাঁক ফেলে দেবে, যেহেতু সেটআপ সেটগুলি সিকোয়েন্সের শেষ মান, পরেরটি নয়।
মিক্ল

6
টেবিলে কোনও সারি না থাকলে আপনার উদাহরণটি কাজ করবে না। সুতরাং সেখানে এসকিউএল প্রদত্ত বেলো আরও নিরাপদ: নির্বাচন করুন সেটওয়াল ('আপনার_সারণযোগ্য_আইডি_সেক', কোলেসেস ((আপনার_সারণী থেকে সর্বোচ্চ (আইডি) +1 নির্বাচন করুন), 1), সত্য));
ভ্যালারি ভিক্টোরিভস্কি

10
@ ভ্যালিরি: তবে উপরের দুটি মন্তব্য কমেন্টের দ্বারা উল্লেখিত ফাঁকগুলি এড়াতে আপনার প্রয়োজনSELECT setval('your_table_id_seq', coalesce((select max(id)+1 from your_table), 1), false);
অ্যান্টনি হ্যাচকিন্স

20
সমস্ত সমস্যার সমাধান এবং একক প্রশ্নের মধ্যে একত্রিত:SELECT setval('your_seq',(SELECT GREATEST(MAX(your_id)+1,nextval('your_seq'))-1 FROM your_table))
ফ্রুনসী

15
যদি আপনার অ্যাপ্লিকেশনটি সিকোয়েন্সগুলির ফাঁকগুলি সম্পর্কে চিন্তা করে তবে আপনার অ্যাপ্লিকেশনটি নষ্ট হয়ে গেছে। ক্রমগুলি গ্যাপগুলি স্বাভাবিক, এবং অপরিকল্পিত ডাটাবেস শাটডাউন, ত্রুটির পরে লেনদেনের রোলব্যাক ইত্যাদির কারণে ঘটতে পারে
ক্রেইগ

202

pg_get_serial_sequenceক্রম নাম সম্পর্কে কোনও ভুল অনুমান এড়াতে ব্যবহার করা যেতে পারে। এটি এক শটে ক্রমটি পুনরায় সেট করে:

SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), (SELECT MAX(id) FROM table_name)+1);

বা আরও সংক্ষিপ্তভাবে:

SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), MAX(id)) FROM table_name;

তবে এই ফর্মটি খালি টেবিলগুলি সঠিকভাবে পরিচালনা করতে পারে না, যেহেতু সর্বোচ্চ (আইডি) নাল, এবং আপনি 0 টি সেটও করতে পারবেন না কারণ এটি ক্রম সীমা ছাড়িয়ে। এর জন্য একটি কর্মসংস্থান হ'ল ALTER SEQUENCEসিনট্যাক্স অর্থাৎ রিসর্ট করা

ALTER SEQUENCE table_name_id_seq RESTART WITH 1;
ALTER SEQUENCE table_name_id_seq RESTART; -- 8.4 or higher

তবে ALTER SEQUENCEসীমিত ব্যবহারের কারণ ক্রম নাম এবং পুনঃসূচনা মানটি এক্সপ্রেশন হতে পারে না cannot

এটি setval"তৃতীয় প্যারামিটার হিসাবে মিথ্যা দিয়ে কল করা সর্বোত্তম উদ্দেশ্য সমাধান হ'ল আমাদের" ব্যবহারের পরবর্তী মান "নির্দিষ্ট করার অনুমতি দেয়:

SELECT setval(pg_get_serial_sequence('t1', 'id'), coalesce(max(id),0) + 1, false) FROM t1;

এটি আমার সমস্ত বাক্সে টিক দেয়:

  1. আসল ক্রম নামটি হার্ড-কোডিং এড়ানো হয়
  2. খালি টেবিলগুলি সঠিকভাবে পরিচালনা করে
  3. বিদ্যমান ডেটা সহ টেবিলগুলি পরিচালনা করে এবং ক্রমের কোনও গর্ত ছেড়ে দেয় না

অবশেষে, নোট করুন যে pg_get_serial_sequenceক্রমটি কলামের মালিকানাধীন হলে কেবলমাত্র কাজ করে। যদি ইনক্রিমেন্টিং কলামটি কোনও serialধরণের হিসাবে সংজ্ঞায়িত করা হয় তবে এটি যদি ক্রমটি ম্যানুয়ালি যুক্ত করা ALTER SEQUENCE .. OWNED BYহয় তবে এটিও সম্পাদন করা হয়েছে তা নিশ্চিত করা প্রয়োজনীয়।

উদাহরণস্বরূপ যদি serialটেবিল তৈরির জন্য টাইপ ব্যবহার করা হত, তবে এটি সমস্ত কাজ করা উচিত:

CREATE TABLE t1 (
  id serial,
  name varchar(20)
);

SELECT pg_get_serial_sequence('t1', 'id'); -- returns 't1_id_seq'

-- reset the sequence, regardless whether table has rows or not:
SELECT setval(pg_get_serial_sequence('t1', 'id'), coalesce(max(id),0) + 1, false) FROM t1;

তবে যদি ক্রমগুলি ম্যানুয়ালি যুক্ত করা হয়:

CREATE TABLE t2 (
  id integer NOT NULL,
  name varchar(20)
);

CREATE SEQUENCE t2_custom_id_seq
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

ALTER TABLE t2 ALTER COLUMN id SET DEFAULT nextval('t2_custom_id_seq'::regclass);

ALTER SEQUENCE t2_custom_id_seq OWNED BY t2.id; -- required for pg_get_serial_sequence

SELECT pg_get_serial_sequence('t2', 'id'); -- returns 't2_custom_id_seq'

-- reset the sequence, regardless whether table has rows or not:
SELECT setval(pg_get_serial_sequence('t2', 'id'), coalesce(max(id),0) + 1, false) FROM t1;

11
ক্যোয়ারিতে '+1' এর কোনও প্রয়োজন নেই, setval()বর্তমান মান নির্ধারণ করে এবং nextval()ইতিমধ্যে বর্তমান মান +1 প্রদান করবে।
অ্যান্টনি হ্যাচকিন্স

1
: ফাংশন এই পদ্ধতি যে এক প্যারামিটার নেয় মোড়কে - - TABLE_NAME নিচে আমার উত্তর হল stackoverflow.com/a/13308052/237105
অ্যান্টনি Hatchkins

পছন্দ করুন
সবেমাত্র

98

সবচেয়ে কম ও দ্রুততম উপায়:

SELECT setval('tbl_tbl_id_seq', max(tbl_id)) FROM tbl;

tbl_idহচ্ছে serialটেবিলের কলাম tbl, ক্রম থেকে অঙ্কন tbl_tbl_id_seq(যা ডিফল্ট স্বয়ংক্রিয় নাম)।

আপনি যদি সংযুক্ত ক্রমের নামটি জানেন না (যা ডিফল্ট আকারে থাকতে হবে না), ব্যবহার করুন pg_get_serial_sequence():

SELECT setval(pg_get_serial_sequence('tbl', 'tbl_id'), max(tbl_id)) FROM tbl;

এখানে কোনও বাইরের ত্রুটি নেই। প্রতি ডকুমেন্টেশন:

দ্বি-পরামিতি ফর্মটি সিক্যুয়েন্সের last_valueক্ষেত্রকে নির্দিষ্ট মান হিসাবে সেট করে এবং তার is_calledক্ষেত্রটিকে সত্যে সেট করে , যার অর্থ পরবর্তীটিnextval কোনও মান ফেরত দেওয়ার আগে ক্রমটি অগ্রসর করবে

বোল্ড জোর আমার।

যদি টেবিল খালি হতে পারে এবং আসলে এই ক্ষেত্রে 1 থেকে শুরু হয়:

SELECT setval(pg_get_serial_sequence('tbl', 'tbl_id')
            , COALESCE(max(tbl_id) + 1, 1)
            , false)
FROM tbl;

আমরা কেবলমাত্র 2-প্যারামেটার ফর্মটি ব্যবহার করতে পারি না এবং শুরু করতে পারি না 0কারণ ক্রমগুলির নীচের সীমাটি ডিফল্ট হিসাবে 1 হয় (কাস্টমাইজ না হওয়া পর্যন্ত)।

concurrency

সমবর্তী ক্রম ক্রিয়াকলাপের বিরুদ্ধে কোনও প্রতিরক্ষা নেই বা উপরের প্রশ্নাগুলিতে এখনও সারণিতে লেখেন। যদি এটি প্রাসঙ্গিক হয় তবে আপনি টেবিলটিকে একচেটিয়া মোডে লক করতে পারেন । আপনি সিঙ্ক করার চেষ্টা করার সময় এটি একটি উচ্চতর সংখ্যা লেখা থেকে একসাথে লেনদেনগুলি রাখে। (এটি অস্থায়ীভাবে সর্বাধিক সংখ্যার সাথে গোলযোগ না করে নিরীহ লেখাগুলিও ব্লক করে blocks)

তবে এটি ক্লায়েন্টদের বিবেচনায় নেয় না যেগুলি প্রধান টেবিলের কোনও লক ছাড়াই অগ্রিম সিকোয়েন্স নম্বর পেয়েছিল, (যা ঘটতে পারে)। এটির জন্যও, কেবলমাত্র ক্রমটির বর্তমান মান বাড়ান , এটি কখনই হ্রাস করবেন না। এটি অদ্ভুত বলে মনে হতে পারে তবে এটি সিকোয়েন্সগুলির প্রকৃতির সাথে সামঞ্জস্যপূর্ণ এবং সম্মতিযুক্ত ইস্যুগুলির বিরুদ্ধে রক্ষা করছে।

BEGIN;

LOCK TABLE tbl IN EXCLUSIVE MODE;

SELECT setval('tbl_tbl_id_seq', max(tbl_id))
FROM   tbl
HAVING max(tbl_id) > (SELECT last_value FROM tbl_tbl_id_seq);

COMMIT;

"স্ট্যান্ডার্ড সম্প্রদায়-প্রয়োজনীয় ফাংশনগুলির লাইব্রেরি" কোথায়? এই উত্তরটির দ্বিতীয় নির্বাচিত ধারাটি EXECUTE format()(@ ইবি'র মতো) একটি প্রয়োজনীয় কাজ! PostgreSQL এ স্ট্যান্ডার্ড লাইব্রেরির এই অভাব কীভাবে সমাধান করবেন ????
পিটার ক্রাউস

না ব্যাপার সেখানে একটি বন্ধ-বাই-এক করে। সিকোয়েন্সগুলিতে গ্যাপগুলি স্বাভাবিক। যদি আপনার অ্যাপ্লিকেশনটি যদি এটি মোকাবেলা করতে না পারে তবে আপনার অ্যাপ্লিকেশনটি ভেঙে গেছে, কারণ লেনদেন রোলব্যাক, অপরিকল্পিত সার্ভার শাটডাউন ইত্যাদির কারণে ফাঁকগুলিও দেখা দিতে পারে
ক্রেগ

1
@ ক্রেইগ: আমি উল্লিখিত অফ-ওয়ান ত্রুটিটি বিষয়টি বিবেচনা করবে (এবং সেখানে নেই) যেহেতু আমরা ডুপ্লিকেট কী ত্রুটিটিকে অন্যথায় ঝুঁকিপূর্ণ করব। আপনার বিবেচনার বিপরীত দিক; একটি ভুল বোঝাবুঝির মত মনে হচ্ছে।
এরউইন ব্র্যান্ডসটেটার

আহ, বোধগম্য হয়।
ক্রেগ রিঞ্জার

এটি আমার জন্য কাজ করে
হেক্টর

54

এটি সর্বজনীন থেকে সারণী বা কলামের নাম সম্পর্কে কোনও অনুমান না করে সমস্ত ক্রম পুনরায় সেট করবে। 8.4 সংস্করণে পরীক্ষিত

CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text, columnname text, sequence_name text) RETURNS "pg_catalog"."void" AS 

    $body$  
      DECLARE 
      BEGIN 

      EXECUTE 'SELECT setval( ''' || sequence_name  || ''', ' || '(SELECT MAX(' || columnname || ') FROM ' || tablename || ')' || '+1)';



      END;  

    $body$  LANGUAGE 'plpgsql';


    select table_name || '_' || column_name || '_seq', reset_sequence(table_name, column_name, table_name || '_' || column_name || '_seq') from information_schema.columns where column_default like 'nextval%';

1
+1 খুব দরকারী ফাংশন! আমাদের সিকোয়েন্সের নামগুলি টেবিলের নামগুলির সাথে ঠিক মেলে না, তাই আমি substring(column_default, '''(.*)''')পরিবর্তে ব্যবহার করেছি table_name || '_' || column_name || '_seq'। পুরোপুরি কাজ করে।
ক্রিস Lerher

4
মনে রাখবেন যে এটি একক উদ্ধৃতি সমেত ক্রমের নাম বা তাদের নামে মূলধন, ফাঁকা স্থানগুলি সহ টেবিলের নামগুলি সহ ব্যর্থ হবে। quote_literalএবং quote_identফাংশন, বা বিশেষ formatফাংশন, সত্যিই এখানে ব্যবহার করা উচিত।
ক্রেগ রিঞ্জার

2
যদি আমি এই একাধিক ভোট দিতে পারি ... সুন্দরভাবে স্যার। কমপক্ষে আমার জন্যও পোস্টগ্রিস 9.1 তে দুর্দান্ত কাজ করে।
পিলম্যান

1
এটা অসাধারণ. আমি substring(column_default from 'nextval\(''(.+)''::regclass\)')স্পষ্টভাবে ক্রম নাম দখল করতাম । কবজির মতো কাজ করেছেন।
ম্যাথু ম্যাকডোনাল্ড

আমি এখন এক দিনেরও বেশি সময় এই সমাধানটির সন্ধান করছিলাম, অনেক ধন্যবাদ, এমনকি আমি পাঠ্যটি প্রতিস্থাপনের জন্য @ ক্রিসলারচারের প্রস্তাবিত পদ্ধতিটি ব্যবহার করেছিsubstring(column_default, '''(.*)''') instead of table_name || '_' || column_name || '_seq'
সুশিন

43

সিক্যুয়েন্স সিকোয়েন্স_নামার সাথে পুনরায় চালু করুন (সারণী সারণি_নাম থেকে সর্বোচ্চ (আইডি) নির্বাচন করুন; কাজ করে না।

@ টার্ডেট উত্তর থেকে অনুলিপি:

SELECT setval(pg_get_serial_sequence('table_name', 'id'), MAX(id)) FROM table_name;

8
এটি আমার জন্য .4.৪ (একটি সিলেক্ট ...) এ একটি সিনট্যাক্স ত্রুটিযুক্ত only (নির্বাচন করুন) এ পুনরায় আরম্ভ করুন only আইডি) FROM
টেবিলের নাম

1
মুরুজেসের সমাধান 9.4-এও কাজ করে না। এই উত্তরে কেন এত বেশি আপত্তি তা বুঝতে পারছেন না। পরিবর্তিত সিকোয়েন্স subqueries অনুমতি দেয় না। @ টার্টেট দ্বারা সমাধান পুরোপুরি কার্যকর করে। ভুল তথ্য মুছে ফেলার জন্য সম্পাদিত উত্তর।
ভ্লাদিস্লাভ রাস্ট্রুসনি

ALTER SEQUENCE আমার জন্য নিখুঁত কাজ করেছে। আমি কিছু ডেটা আনতে কপি ব্যবহার করেছি এবং প্রাথমিক কীগুলিতে ফাঁক ছিল এবং INSERT এর সদৃশ কী ব্যতিক্রম ছুঁড়ে মারছিল। ক্রম নির্ধারণ করা কৌশলটি করেছে। 9.4
ব্যবহারকারী542319

22

পোস্টগ্রিসক্লিতে কেবলমাত্র স্বয়ংক্রিয় উত্পন্ন কী সিকোয়েন্সের মান পরিবর্তন করার জন্য এই কমান্ডটি

ALTER SEQUENCE "your_sequence_name" RESTART WITH 0;

শূন্যের জায়গায় আপনি যে কোনও নম্বর থেকে ক্রম পুনরায় আরম্ভ করতে চান এমন কোনও সংখ্যা রাখতে পারেন।

ডিফল্ট ক্রম নাম হবে "TableName_FieldName_seq"। উদাহরণস্বরূপ, যদি আপনার টেবিলের নাম "MyTable"এবং আপনার ক্ষেত্রের নাম হয় "MyID"তবে আপনার ক্রমের নামটি হবে "MyTable_MyID_seq"

এই উত্তরটি @ মুর্গেস্পোনাপানের উত্তর হিসাবে একই, তবে তার সমাধানে একটি বাক্য গঠন ত্রুটি রয়েছে। আপনি উপ ক্যোয়ারী ব্যবহার করতে পারবেন না (select max()...)alterকমান্ড। যাতে হয় আপনাকে নির্দিষ্ট সংখ্যাসূচক মানটি ব্যবহার করতে হবে অথবা আপনাকে সাব কোয়েরির স্থানে একটি ভেরিয়েবল ব্যবহার করতে হবে।


এই নিখুঁত সমাধান স্যার আপনাকে অনেক ধন্যবাদ। তবে আমার ক্ষেত্রে আমার একটি ত্রুটি হয়েছিল, সুতরাং আমাকে এটিকে ALTER SEQUENCE "আপনার_সাম্য_নাম" "1 দিয়ে পুনরায় চালু করতে হবে;
Deunz

18

সমস্ত সিকোয়েন্স পুনরায় সেট করুন, নামগুলির বিষয়ে কোনও অনুমান ব্যতীত প্রতিটি টেবিলের প্রাথমিক কী "আইডি":

CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text, columnname text)
RETURNS "pg_catalog"."void" AS
$body$
DECLARE
BEGIN
    EXECUTE 'SELECT setval( pg_get_serial_sequence(''' || tablename || ''', ''' || columnname || '''),
    (SELECT COALESCE(MAX(id)+1,1) FROM ' || tablename || '), false)';
END;
$body$  LANGUAGE 'plpgsql';

select table_name || '_' || column_name || '_seq', reset_sequence(table_name, column_name) from information_schema.columns where column_default like 'nextval%';

আমার 9.1 সংস্করণে পুরোপুরি কাজ করেছেন
ভ্যালেন্টিন ভ্যাসিলিভ

টেবিলের উপরের ক্ষেত্রে উপস্থিত থাকলে আপনার উদ্ধৃতি যুক্ত করতে হবে:pg_get_serial_sequence(''"' || tablename || '"''
ম্যানুয়েল ডারভউ

এটি সেরা অনুষ্ঠান! আপনি বিন্যাসের সাথে উদ্ধৃতি সমস্যাগুলি (এবং কমনীয়তা বাড়ানোর) এড়াতে পারেন, এরকম কিছু EXECUTE format( 'SELECT setval(pg_get_serial_sequence(%L, %L), coalesce(max(id),0) + 1, false) FROM %I;', $1,$2,$1 );
পিটার ক্রাউস

13

ক্রমের নাম, কলামের নাম, টেবিলের নাম বা স্কিমার নামগুলিতে ফাঁক, বিরাম চিহ্ন এবং এর মতো মজাদার অক্ষর থাকলে এই ফাংশনগুলি বিপদে পরিপূর্ণ থাকে। আমি এটি লিখেছি:

CREATE OR REPLACE FUNCTION sequence_max_value(oid) RETURNS bigint
VOLATILE STRICT LANGUAGE plpgsql AS  $$
DECLARE
 tabrelid oid;
 colname name;
 r record;
 newmax bigint;
BEGIN
 FOR tabrelid, colname IN SELECT attrelid, attname
               FROM pg_attribute
              WHERE (attrelid, attnum) IN (
                      SELECT adrelid::regclass,adnum
                        FROM pg_attrdef
                       WHERE oid IN (SELECT objid
                                       FROM pg_depend
                                      WHERE refobjid = $1
                                            AND classid = 'pg_attrdef'::regclass
                                    )
          ) LOOP
      FOR r IN EXECUTE 'SELECT max(' || quote_ident(colname) || ') FROM ' || tabrelid::regclass LOOP
          IF newmax IS NULL OR r.max > newmax THEN
              newmax := r.max;
          END IF;
      END LOOP;
  END LOOP;
  RETURN newmax;
END; $$ ;

আপনি এটিকে ওআইডি পাস করে একক ক্রমের জন্য কল করতে পারেন এবং এটি যে কোনও সারণীর দ্বারা ব্যবহৃত সর্বাধিক সংখ্যাটি ডিফল্ট হিসাবে সিকোয়েন্স যুক্ত করবে; অথবা আপনি এটি আপনার ডেটাবেজে সমস্ত সিকোয়েন্স পুনরায় সেট করতে এই জাতীয় একটি কোয়েরি দিয়ে চালাতে পারেন:

 select relname, setval(oid, sequence_max_value(oid))
   from pg_class
  where relkind = 'S';

আলাদা কোয়ালিটি ব্যবহার করে আপনি নির্দিষ্ট স্কিমায় কেবল ক্রমটি পুনরায় সেট করতে পারেন। উদাহরণস্বরূপ, আপনি যদি "সার্বজনীন" স্কিমাতে ক্রমগুলি সামঞ্জস্য করতে চান:

select relname, setval(pg_class.oid, sequence_max_value(pg_class.oid))
  from pg_class, pg_namespace
 where pg_class.relnamespace = pg_namespace.oid and
       nspname = 'public' and
       relkind = 'S';

নোট করুন যে সেটআপ () কীভাবে কাজ করে তার কারণে আপনাকে ফলাফলটিতে 1 যোগ করার দরকার নেই।

একটি সমাপনী নোট হিসাবে, আমাকে সতর্ক করতে হবে যে কিছু ডাটাবেসে সিস্টেমের ক্যাটালগগুলিতে সম্পূর্ণ তথ্য থাকতে দেয় না এমন উপায়ে সিকোয়েন্সগুলির সাথে সংযোগ স্থাপনের ডিফল্ট মনে হয়। আপনি যখন পিএসএলএল এর \ d তে এরকম জিনিস দেখতে পান তখন এটি ঘটে:

alvherre=# \d baz
                     Tabla «public.baz»
 Columna |  Tipo   |                 Modificadores                  
---------+---------+------------------------------------------------
 a       | integer | default nextval(('foo_a_seq'::text)::regclass)

নোট করুন যে ডিফল্ট ধারাটিতে পরের () কলটিতে :: রেজগ্লাসের কাস্ট ছাড়াও একটি :: পাঠ্য কাস্ট রয়েছে। আমি মনে করি এটি পুরাতন PostgreSQL সংস্করণ থেকে pg_dump'd করা ডাটাবেসের কারণে is কি হবে তা হ'ল উপরের ক্রিয়াকলাপটি ক্রম_ম্যাক্স_ভ্যালু () এই জাতীয় সারণিকে উপেক্ষা করবে। সমস্যা সমাধানের জন্য, আপনি সরাসরি castালাই ছাড়াই অনুক্রমটি উল্লেখ করতে ডিফল্ট ধারাটি পুনরায় সংজ্ঞায়িত করতে পারেন:

alvherre=# alter table baz alter a set default nextval('foo_a_seq');
ALTER TABLE

তারপরে পিএসকিএল এটিকে সঠিকভাবে প্রদর্শন করে:

alvherre=# \d baz
                     Tabla «public.baz»
 Columna |  Tipo   |             Modificadores              
---------+---------+----------------------------------------
 a       | integer | default nextval('foo_a_seq'::regclass)

যত তাড়াতাড়ি আপনি এটি স্থির করেছেন, ফাংশনটি এই টেবিলের পাশাপাশি একই ক্রম ব্যবহার করতে পারে এমন সমস্ত অন্যদের জন্য সঠিকভাবে কাজ করে।


এটি আশ্চর্যজনক থেক্স! এটি নোট করা উচিত যে আমাকে এই ধরনের অ্যাসাইনমেন্টে (ফাংশন কোডের 21 লাইন) একটি কাস্ট যোগ করার দরকার ছিল: newmax := r.max::bigint;এটি আমার জন্য সঠিকভাবে কাজ করার জন্য।
টমি ব্রাভো

এটিও পরিবর্তন করতে হয়েছিল: 'SELECT max(' || quote_ident(colname) || ') FROM ' => গতিশীলভাবে বিল্ড ক্যোয়ারির মধ্যে 'SELECT max(' || quote_ident(colname) || '::bigint) FROM ' যুক্ত ::bigintকাস্টটি লক্ষ্য করুন ।
টমি ব্রাভো

9

তবুও অন্য plpgsql - কেবলমাত্র যদি পুনরায় সেট করা হয় max(att) > then lastval

do --check seq not in sync
$$
declare
 _r record;
 _i bigint;
 _m bigint;
begin
  for _r in (
    SELECT relname,nspname,d.refobjid::regclass, a.attname, refobjid
    FROM   pg_depend    d
    JOIN   pg_attribute a ON a.attrelid = d.refobjid AND a.attnum = d.refobjsubid
    JOIN pg_class r on r.oid = objid
    JOIN pg_namespace n on n.oid = relnamespace
    WHERE  d.refobjsubid > 0 and  relkind = 'S'
   ) loop
    execute format('select last_value from %I.%I',_r.nspname,_r.relname) into _i;
    execute format('select max(%I) from %s',_r.attname,_r.refobjid) into _m;
    if coalesce(_m,0) > _i then
      raise info '%',concat('changed: ',_r.nspname,'.',_r.relname,' from:',_i,' to:',_m);
      execute format('alter sequence %I.%I restart with %s',_r.nspname,_r.relname,_m+1);
    end if;
  end loop;

end;
$$
;

লাইনে মন্তব্য করাও --execute format('alter sequenceতালিকাটি দেবে, প্রকৃতপক্ষে মানটি পুনরায় সেট করে না


8

সমস্ত ক্রম সর্বজনীন থেকে পুনরায় সেট করুন

CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text) RETURNS "pg_catalog"."void" AS 
$body$  
  DECLARE 
  BEGIN 
  EXECUTE 'SELECT setval( ''' 
  || tablename  
  || '_id_seq'', ' 
  || '(SELECT id + 1 FROM "' 
  || tablename  
  || '" ORDER BY id DESC LIMIT 1), false)';  
  END;  
$body$  LANGUAGE 'plpgsql';

select sequence_name, reset_sequence(split_part(sequence_name, '_id_seq',1)) from information_schema.sequences
        where sequence_schema='public';

দেখা যাচ্ছে যে এই পদ্ধতিটি কলাম এবং টেবিলের নামগুলি সম্পর্কে অনুমান করে যাতে এটি আমার পক্ষে কাজ করে না
djsnowsill

ডাটাবেসে সেই ডেটা ক্ষতি করবে না?
জেনিনিন

8

আমি পোস্টগ্রিস উইকিতে পাওয়া এই সমাধানটির পরামর্শ দিই। এটি আপনার টেবিলগুলির সমস্ত ক্রম আপডেট করে।

SELECT 'SELECT SETVAL(' ||
       quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) ||
       ', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' ||
       quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';'
FROM pg_class AS S,
     pg_depend AS D,
     pg_class AS T,
     pg_attribute AS C,
     pg_tables AS PGT
WHERE S.relkind = 'S'
    AND S.oid = D.objid
    AND D.refobjid = T.oid
    AND D.refobjid = C.attrelid
    AND D.refobjsubid = C.attnum
    AND T.relname = PGT.tablename
ORDER BY S.relname;

কীভাবে ব্যবহার করবেন (পোস্টগ্রিস উইকি থেকে):

  • এটিকে একটি ফাইলে সংরক্ষণ করুন, 'রিসেট.এসকিউএল' বলুন
  • ফাইলটি চালান এবং এর আউটপুট এমনভাবে সংরক্ষণ করুন যাতে স্বাভাবিক শিরোনাম অন্তর্ভুক্ত না হয়, তারপরে সেই আউটপুটটি চালান। উদাহরণ:

উদাহরণ:

psql -Atq -f reset.sql -o temp
psql -f temp
rm temp

মূল নিবন্ধ (ক্রম মালিকানার জন্য স্থির সহ) এখানেও


7

কিছু সত্যিকারের কঠোর উত্তর এখানে রয়েছে, আমি ধরে নিচ্ছি যে এটি যখন জিজ্ঞাসা করা হয়েছিল তখন প্রায় এটি খুব খারাপ হত, কারণ এখান থেকে প্রচুর উত্তর 9.3 সংস্করণে কাজ করে না। ডকুমেন্টেশন সংস্করণ 8.0 থেকে এই খুব প্রশ্নের উত্তর প্রদান করে:

SELECT setval('serial', max(id)) FROM distributors;

এছাড়াও, যদি কেস-সেনসিটিভ সিকোয়েন্সের নামগুলির যত্ন নেওয়া দরকার তবে আপনি এটিই করেন:

SELECT setval('"Serial"', max(id)) FROM distributors;

7

এই সমস্যাটি আমার সাথে ঘটে যখন ডেটাবেস তৈরি করতে সত্তা ফ্রেমওয়ার্ক ব্যবহার করে এবং তারপরে প্রাথমিক ডেটা দিয়ে ডাটাবেস বীজ করে, এটি ক্রমটি মেলেনি।

আমি এটি ডেটাবেস সিড করার পরে চালানোর জন্য একটি স্ক্রিপ্ট তৈরি করে সমাধান করেছি:

DO
$do$
DECLARE tablename text;
BEGIN
    -- change the where statments to include or exclude whatever tables you need
    FOR tablename IN SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE' AND table_name != '__EFMigrationsHistory'
        LOOP
            EXECUTE format('SELECT setval(pg_get_serial_sequence(''"%s"'', ''Id''), (SELECT MAX("Id") + 1 from "%s"))', tablename, tablename);
    END LOOP;
END
$do$

1
MAX("Id") + 1যখন সিকোয়েন্সটি সর্বাধিক = যখন হয় তখন কেন এটি আমার পক্ষে সেরা কাজ করে।
লাস্টলিঙ্ক

6

আমার সংস্করণটি প্রথমটি ব্যবহার করে কিছু ত্রুটি পরীক্ষা করে ...

BEGIN;
CREATE OR REPLACE FUNCTION reset_sequence(_table_schema text, _tablename text, _columnname text, _sequence_name text)
RETURNS pg_catalog.void AS
$BODY$
DECLARE
BEGIN
 PERFORM 1
 FROM information_schema.sequences
 WHERE
  sequence_schema = _table_schema AND
  sequence_name = _sequence_name;
 IF FOUND THEN
  EXECUTE 'SELECT setval( ''' || _table_schema || '.' || _sequence_name  || ''', ' || '(SELECT MAX(' || _columnname || ') FROM ' || _table_schema || '.' || _tablename || ')' || '+1)';
 ELSE
  RAISE WARNING 'SEQUENCE NOT UPDATED ON %.%', _tablename, _columnname;
 END IF;
END; 
$BODY$
 LANGUAGE 'plpgsql';

SELECT reset_sequence(table_schema, table_name, column_name, table_name || '_' || column_name || '_seq')
FROM information_schema.columns
WHERE column_default LIKE 'nextval%';

DROP FUNCTION reset_sequence(_table_schema text, _tablename text, _columnname text, _sequence_name text) ;
COMMIT;

ত্রুটি পরীক্ষা করার জন্য আপনাকে ধন্যবাদ! টেবিল / কলামের নামগুলি যদি খুব বেশি দীর্ঘ হয় তবে তারা আপনাকে RAISE WARNINGআমার জন্য চিহ্নিত করেছে বলে অনেক প্রশংসা করা হয়েছে ।
নিকোলাস রিলি

5

সবগুলোকে একত্রে রাখ

CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text) 
RETURNS "pg_catalog"."void" AS
$body$
DECLARE
BEGIN
  EXECUTE 'SELECT setval( pg_get_serial_sequence(''' || tablename || ''', ''id''),
  (SELECT COALESCE(MAX(id)+1,1) FROM ' || tablename || '), false)';
END;
$body$  LANGUAGE 'plpgsql';

id'প্রদত্ত টেবিলের ক্রমটি ঠিক করবে (উদাহরণস্বরূপ জাজানো সহ সাধারণত প্রয়োজনীয়)।


4

আমি এখনও কোডটি চেষ্টা না করার আগে: নিম্নলিখিতটিতে আমি ক্লাউস এবং ব্যবহারকারীর জন্য 7 solutions solutions২২ solutions সমাধানের জন্য এসকিএল কোডের সংস্করণ পোস্ট করেছি যা আমার পিসিতে পোস্ট করেছে [পোস্টগ্রিস ৮.৩], ক্লাউসের সাথে সামান্য কিছু সামঞ্জস্য রেখে এবং আমার সংস্করণটি ব্যবহারকারীর জন্য 457226 এক।

ক্লাউস সমাধান:

drop function IF EXISTS rebuilt_sequences() RESTRICT;
CREATE OR REPLACE FUNCTION  rebuilt_sequences() RETURNS integer as
$body$
  DECLARE sequencedefs RECORD; c integer ;
  BEGIN
    FOR sequencedefs IN Select
      constraint_column_usage.table_name as tablename,
      constraint_column_usage.table_name as tablename, 
      constraint_column_usage.column_name as columnname,
      replace(replace(columns.column_default,'''::regclass)',''),'nextval(''','') as sequencename
      from information_schema.constraint_column_usage, information_schema.columns
      where constraint_column_usage.table_schema ='public' AND 
      columns.table_schema = 'public' AND columns.table_name=constraint_column_usage.table_name
      AND constraint_column_usage.column_name = columns.column_name
      AND columns.column_default is not null
   LOOP    
      EXECUTE 'select max('||sequencedefs.columnname||') from ' || sequencedefs.tablename INTO c;
      IF c is null THEN c = 0; END IF;
      IF c is not null THEN c = c+ 1; END IF;
      EXECUTE 'alter sequence ' || sequencedefs.sequencename ||' restart  with ' || c;
   END LOOP;

   RETURN 1; END;
$body$ LANGUAGE plpgsql;

select rebuilt_sequences();

ব্যবহারকারী 457226 সমাধান:

--drop function IF EXISTS reset_sequence (text,text) RESTRICT;
CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text,columnname text) RETURNS bigint --"pg_catalog"."void"
AS
$body$
  DECLARE seqname character varying;
          c integer;
  BEGIN
    select tablename || '_' || columnname || '_seq' into seqname;
    EXECUTE 'SELECT max("' || columnname || '") FROM "' || tablename || '"' into c;
    if c is null then c = 0; end if;
    c = c+1; --because of substitution of setval with "alter sequence"
    --EXECUTE 'SELECT setval( "' || seqname || '", ' || cast(c as character varying) || ', false)'; DOES NOT WORK!!!
    EXECUTE 'alter sequence ' || seqname ||' restart with ' || cast(c as character varying);
    RETURN nextval(seqname)-1;
  END;
$body$ LANGUAGE 'plpgsql';

select sequence_name, PG_CLASS.relname, PG_ATTRIBUTE.attname,
       reset_sequence(PG_CLASS.relname,PG_ATTRIBUTE.attname)
from PG_CLASS
join PG_ATTRIBUTE on PG_ATTRIBUTE.attrelid = PG_CLASS.oid
join information_schema.sequences
     on information_schema.sequences.sequence_name = PG_CLASS.relname || '_' || PG_ATTRIBUTE.attname || '_seq'
where sequence_schema='public';

4

পাবলিক স্কিমা ফাংশনে সমস্ত ক্রম পুনরায় পরীক্ষা করুন

CREATE OR REPLACE FUNCTION public.recheck_sequence (
)
RETURNS void AS
$body$
DECLARE
  _table_name VARCHAR;
  _column_name VARCHAR;  
  _sequence_name VARCHAR;
BEGIN
  FOR _table_name IN SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'public' LOOP
    FOR _column_name IN SELECT column_name FROM information_schema.columns WHERE table_name = _table_name LOOP
        SELECT pg_get_serial_sequence(_table_name, _column_name) INTO _sequence_name;
        IF _sequence_name IS NOT NULL THEN 
            EXECUTE 'SELECT setval('''||_sequence_name||''', COALESCE((SELECT MAX('||quote_ident(_column_name)||')+1 FROM '||quote_ident(_table_name)||'), 1), FALSE);';
        END IF;
    END LOOP;   
  END LOOP;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

3

সমস্ত ক্রম 1 টি পুনরায় চালু করতে:

-- Create Function
CREATE OR REPLACE FUNCTION "sy_restart_seq_to_1" (
    relname TEXT
)
RETURNS "pg_catalog"."void" AS
$BODY$

DECLARE

BEGIN
    EXECUTE 'ALTER SEQUENCE '||relname||' RESTART WITH 1;';
END;
$BODY$

LANGUAGE 'plpgsql';

-- Use Function
SELECT 
    relname
    ,sy_restart_seq_to_1(relname)
FROM pg_class
WHERE relkind = 'S';

2

ক্লাউস উত্তরটি সবচেয়ে কার্যকর, কিছুটা মিস করার জন্য কার্যকর: আপনাকে নির্বাচিত বিবৃতিতে DISTINCT যুক্ত করতে হবে।

তবে, আপনি যদি নিশ্চিত হন যে কোনও টেবিল + কলামের নাম দুটি আলাদা আলাদা টেবিলের সমতুল্য না হয় তবে আপনি এটি ব্যবহার করতে পারেন:

select sequence_name, --PG_CLASS.relname, PG_ATTRIBUTE.attname
       reset_sequence(split_part(sequence_name, '_id_seq',1))
from PG_CLASS
join PG_ATTRIBUTE on PG_ATTRIBUTE.attrelid = PG_CLASS.oid
join information_schema.sequences
     on information_schema.sequences.sequence_name = PG_CLASS.relname || '_' || PG_ATTRIBUTE.attname
where sequence_schema='public';

যখন কিছু আগ্রহী কলামের নাম 'আইডি' না হয় তখন ক্ষেত্রে 45457226 এর সমাধানটির এক্সটেনশন।


... অবশ্যই "রিসেট_সেক্সেন্স" এও পরিবর্তন দরকার, এটি "আইডি" এর পরিবর্তে "কলামনাম" পরামিতি যুক্ত করছে।
মারিও

2

আপনি যখন আরম্ভের জন্য কাস্টম এসকিউএল ডেটা লোড করছেন তখন আপনি এই ত্রুটিটি দেখতে পান, এটি এড়ানোর আরেকটি উপায় হ'ল:

লেখার পরিবর্তে:

INSERT INTO book (id, name, price) VALUES (1 , 'Alchemist' , 10),

idপ্রাথমিক তথ্য থেকে (প্রাথমিক কী) সরান

INSERT INTO book (name, price) VALUES ('Alchemist' , 10),

এটি পোস্টগ্রিস ক্রমটিকে সিঙ্কে রাখে!


2

এই উত্তরটি মুরোর একটি অনুলিপি।

drop function IF EXISTS rebuilt_sequences() RESTRICT;
CREATE OR REPLACE FUNCTION  rebuilt_sequences() RETURNS integer as
$body$
  DECLARE sequencedefs RECORD; c integer ;
  BEGIN
    FOR sequencedefs IN Select
      DISTINCT(constraint_column_usage.table_name) as tablename,
      constraint_column_usage.column_name as columnname,
      replace(replace(columns.column_default,'''::regclass)',''),'nextval(''','') as sequencename
      from information_schema.constraint_column_usage, information_schema.columns
      where constraint_column_usage.table_schema ='public' AND 
      columns.table_schema = 'public' AND columns.table_name=constraint_column_usage.table_name
      AND constraint_column_usage.column_name = columns.column_name
      AND columns.column_default is not null 
      ORDER BY sequencename
   LOOP    
      EXECUTE 'select max('||sequencedefs.columnname||') from ' || sequencedefs.tablename INTO c;
      IF c is null THEN c = 0; END IF;
      IF c is not null THEN c = c+ 1; END IF;
      EXECUTE 'alter sequence ' || sequencedefs.sequencename ||' minvalue '||c ||' start ' || c ||' restart  with ' || c;
   END LOOP;

   RETURN 1; END;
$body$ LANGUAGE plpgsql;

select rebuilt_sequences();

2

আমি মিশ্রিত কেস টেবিল এবং কলামগুলি ব্যবহার করে একটি ডাটাবেস নিয়ে কাজ করার জন্য ডিজেএসনোসিলের উত্তর পেতে চেষ্টা করে এক ঘন্টা ব্যয় করেছি, তবে অবশেষে ম্যানুয়েল ডারভের একটি মন্তব্যে সমাধানটির জন্য হোঁচট খেয়েছি, তবে আমি ভেবেছিলাম যে আমি এটিকে সবার জন্য আরও পরিষ্কার করে তুলতে পারি:

CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text, columnname text)
RETURNS "pg_catalog"."void" AS
$body$
DECLARE
BEGIN
EXECUTE format('SELECT setval(pg_get_serial_sequence(''%1$I'', %2$L),
        (SELECT COALESCE(MAX(%2$I)+1,1) FROM %1$I), false)',tablename,columnname);
END;
$body$  LANGUAGE 'plpgsql';

SELECT format('%s_%s_seq',table_name,column_name), reset_sequence(table_name,column_name) 
FROM information_schema.columns WHERE column_default like 'nextval%';

এর সুবিধা রয়েছে:

  • ধরে নেই আইডি কলামটি একটি বিশেষ উপায়ে বানানো হয়েছে।
  • সমস্ত টেবিলের একটি সিকোয়েন্স আছে তা ধরে নিচ্ছি না।
  • মিশ্র কেস টেবিল / কলামের নামগুলির জন্য কাজ করা।
  • আরও সংক্ষিপ্ত হতে ফর্ম্যাট ব্যবহার করে।

ব্যাখ্যা করার জন্য, সমস্যাটি হ'ল pg_get_serial_sequenceআপনি যা উল্লেখ করছেন তা কার্যকর করতে স্ট্রিংগুলি লাগে, তাই আপনি যদি করেন:

"TableName" --it thinks it's a table or column
'TableName' --it thinks it's a string, but makes it lower case
'"TableName"' --it works!

এটি ''%1$I''ফর্ম্যাট স্ট্রিংয়ের সাহায্যে অর্জন করা হয়, ''একটি অ্যাস্টোস্ট্রোফের 1$অর্থ প্রথম আর্গ তৈরি করে এবং এর Iঅর্থ উদ্ধৃতিতে


1

কিছু শেল যাদু ব্যবহার করে এটি ঠিক করার জন্য কুৎসিত হ্যাক, দুর্দান্ত সমাধান নয় তবে অন্যদেরকে অনুরূপ সমস্যা নিয়ে উদ্বুদ্ধ করতে পারে :)

pg_dump -s <DATABASE> | grep 'CREATE TABLE' | awk '{print "SELECT setval(#" $3 "_id_seq#, (SELECT MAX(id) FROM " $3 "));"}' | sed "s/#/'/g" | psql <DATABASE> -f -

1
select 'SELECT SETVAL(' || seq [ 1] || ', COALESCE(MAX('||column_name||')+1, 1) ) FROM '||table_name||';'
from (
       SELECT table_name, column_name, column_default, regexp_match(column_default, '''.*''') as seq
       from information_schema.columns
       where column_default ilike 'nextval%'
     ) as sequense_query

4
এই কোডটি প্রশ্নের উত্তর দিতে পারে, কেন এবং / অথবা এই কোডটির প্রশ্নের উত্তর কীভাবে তার দীর্ঘমেয়াদী মানকে উন্নত করে সে সম্পর্কে অতিরিক্ত প্রসঙ্গ সরবরাহ করে।
ইয়েয়া

0

রিইনডেক্স চেষ্টা করুন

আপডেট: মন্তব্যগুলিতে যেমন উল্লেখ করা হয়েছে, এটি মূল প্রশ্নের উত্তরে ছিল।


রিইনডেক্স কাজ করে নি, এটি কেবল
সূচিটি

3
রিইনডেক্স কাজ করে না কারণ এটি আপনার মূল প্রশ্নের উত্তর
দিচ্ছিল

0

SELECT setval... জেডিবিসিকে বার্ক বানায়, তাই এটি করার একটি জাভা-সামঞ্জস্যপূর্ণ উপায়:

-- work around JDBC 'A result was returned when none was expected.'
-- fix broken nextval due to poorly written 20140320100000_CreateAdminUserRoleTables.sql
DO 'BEGIN PERFORM setval(pg_get_serial_sequence(''admin_user_role_groups'', ''id''), 1 + COALESCE(MAX(id), 0), FALSE) FROM admin_user_role_groups; END;';

0

আপনার স্কিমাতে সমস্ত ক্রম আপডেট করার একটি পদ্ধতি যা আইডি হিসাবে ব্যবহৃত হয়:

DO $$ DECLARE
  r RECORD;
BEGIN
FOR r IN (SELECT tablename, pg_get_serial_sequence(tablename, 'id') as sequencename
          FROM pg_catalog.pg_tables
          WHERE schemaname='YOUR_SCHEMA'
          AND tablename IN (SELECT table_name 
                            FROM information_schema.columns 
                            WHERE table_name=tablename and column_name='id')
          order by tablename)
LOOP
EXECUTE
        'SELECT setval(''' || r.sequencename || ''', COALESCE(MAX(id), 1), MAX(id) IS NOT null)
         FROM ' || r.tablename || ';';
END LOOP;
END $$;


0

এখানে অনেক ভাল উত্তর আছে। আমার জ্যাঙ্গো ডাটাবেস পুনরায় লোড করার পরে আমারও একই প্রয়োজন ছিল।

তবে আমার প্রয়োজন:

  • সবই এক ফাংশনে
  • একসাথে এক বা একাধিক স্কিমা ঠিক করতে পারে
  • একসাথে সমস্ত বা কেবল একটি টেবিল ঠিক করতে পারে
  • ঠিক কী বদলেছে বা কী পরিবর্তন হয়নি তা দেখার একটি দুর্দান্ত উপায়ও চেয়েছিলেন

এটি মূল জিজ্ঞাসাটির সাথে খুব অনুরূপ প্রয়োজন বলে মনে হয়।
বলডিরির জন্য ধন্যবাদ এবং মুরো আমাকে সঠিক পথে পৌঁছেছে।

drop function IF EXISTS reset_sequences(text[], text) RESTRICT;
CREATE OR REPLACE FUNCTION reset_sequences(
    in_schema_name_list text[] = '{"django", "dbaas", "metrics", "monitor", "runner", "db_counts"}',
    in_table_name text = '%') RETURNS text[] as
$body$
  DECLARE changed_seqs text[];
  DECLARE sequence_defs RECORD; c integer ;
  BEGIN
    FOR sequence_defs IN
        select
          DISTINCT(ccu.table_name) as table_name,
          ccu.column_name as column_name,
          replace(replace(c.column_default,'''::regclass)',''),'nextval(''','') as sequence_name
          from information_schema.constraint_column_usage ccu,
               information_schema.columns c
          where ccu.table_schema = ANY(in_schema_name_list)
            and ccu.table_schema = c.table_schema
            AND c.table_name = ccu.table_name
            and c.table_name like in_table_name
            AND ccu.column_name = c.column_name
            AND c.column_default is not null
          ORDER BY sequence_name
   LOOP
      EXECUTE 'select max(' || sequence_defs.column_name || ') from ' || sequence_defs.table_name INTO c;
      IF c is null THEN c = 1; else c = c + 1; END IF;
      EXECUTE 'alter sequence ' || sequence_defs.sequence_name || ' restart  with ' || c;
      changed_seqs = array_append(changed_seqs, 'alter sequence ' || sequence_defs.sequence_name || ' restart with ' || c);
   END LOOP;
   changed_seqs = array_append(changed_seqs, 'Done');

   RETURN changed_seqs;
END
$body$ LANGUAGE plpgsql;

তারপরে কার্যকর হওয়া এবং পরিবর্তনগুলি চালিত দেখতে:

select *
from unnest(reset_sequences('{"django", "dbaas", "metrics", "monitor", "runner", "db_counts"}'));

রিটার্নস

activity_id_seq                          restart at 22
api_connection_info_id_seq               restart at 4
api_user_id_seq                          restart at 1
application_contact_id_seq               restart at 20
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.