PostgreSQL এ, আমি কীভাবে একটি টেবিলের মধ্যে শেষ আইডি ?োকানো করব?
এমএস এসকিউএলে রয়েছে SCOPE_IDENTITY ()।
দয়া করে আমাকে এই জাতীয় কিছু ব্যবহার করার পরামর্শ দিবেন না:
select max(id) from table
PostgreSQL এ, আমি কীভাবে একটি টেবিলের মধ্যে শেষ আইডি ?োকানো করব?
এমএস এসকিউএলে রয়েছে SCOPE_IDENTITY ()।
দয়া করে আমাকে এই জাতীয় কিছু ব্যবহার করার পরামর্শ দিবেন না:
select max(id) from table
উত্তর:
( tl;dr
: গোটো অপশন 3: প্রত্যাবর্তনের সাথে অন্তর্ভুক্ত)
মনে রাখবেন যে পোস্টগ্র্যাস্কল-এ টেবিলের জন্য কোনও "আইডি" ধারণা নেই, কেবল সিকোয়েন্সগুলি (যা সাধারণত তবে সেরিয়াল সিউডো টাইপ সহ সারোগেট প্রাথমিক কীগুলির জন্য ডিফল্ট মান হিসাবে ব্যবহৃত হয় না )।
আপনি যদি সদ্য inোকানো সারিটির আইডি পেতে আগ্রহী হন তবে কয়েকটি উপায় রয়েছে:
বিকল্প 1: CURRVAL(<sequence name>);
।
উদাহরণ স্বরূপ:
INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John');
SELECT currval('persons_id_seq');
ক্রমের নামটি অবশ্যই জানা উচিত, এটি সত্যই স্বেচ্ছাসেবী; এই উদাহরণে আমরা ধরে নিই যে ছকটি সিউডো-টাইপ দিয়ে তৈরি persons
একটি id
কলাম তৈরি করেছে SERIAL
। এটির উপর নির্ভর না করা এবং আরও পরিষ্কার অনুভব করতে আপনি এর পরিবর্তে ব্যবহার করতে পারেন pg_get_serial_sequence
:
INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John');
SELECT currval(pg_get_serial_sequence('persons','id'));
ক্যাভ্যাট: একই অধিবেশনটিতেcurrval()
কেবল INSERT
(যা কার্যকর করা হয়েছে nextval()
) পরে কাজ করে ।
বিকল্প 2: LASTVAL();
এটি পূর্ববর্তীগুলির মতো, কেবলমাত্র আপনার সিক্যুয়েন্স নামটি নির্দিষ্ট করার দরকার নেই: এটি সর্বাধিক সাম্প্রতিক পরিবর্তিত অনুক্রমের সন্ধান করে (সর্বদা আপনার সেশনের অভ্যন্তরে, উপরের মতো একই ক্যাভেট)।
CURRVAL
এবং উভয়ই LASTVAL
সম্পূর্ণ একযোগে নিরাপদ। পিজিতে ক্রমক্রমের আচরণটি এমনভাবে তৈরি করা হয়েছে যাতে বিভিন্ন অধিবেশন হস্তক্ষেপ না করে, তাই জাতিদের অবস্থার ঝুঁকি নেই (যদি অন্য সেশনটি আমার INSERT এবং আমার নির্বাচনীর মধ্যে অন্য সারি সন্নিবেশ করায় তবে আমি আমার সঠিক মান পাই)।
তবে তাদের একটি সূক্ষ্ম সম্ভাব্য সমস্যা আছে। ডাটাবেসে যদি কিছু ট্রিগার (বা RULE) থাকে যা persons
সারণীতে সন্নিবেশ করানোর সাথে সাথে অন্য টেবিলগুলিতে কিছু অতিরিক্ত সন্নিবেশ LASTVAL
করায় ... তবে সম্ভবত আমাদের ভুল মান দেবে। সমস্যাটি এমনকি যদি ঘটতে পারে CURRVAL
তবে একই persons
সারণীতে অতিরিক্ত সন্নিবেশ সম্পন্ন করা হলে (এটি স্বাভাবিকের তুলনায় অনেক কম, তবে ঝুঁকিটি এখনও বিদ্যমান)।
বিকল্প 3: INSERT
সহRETURNING
INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John') RETURNING id;
এটি আইডি পাওয়ার সবচেয়ে পরিষ্কার, দক্ষ এবং নিরাপদ উপায় efficient এটির আগের কোনও ঝুঁকি নেই।
অপূর্ণতা? প্রায় কোনওটিই নয়: আপনি আপনার ইনসার্ট স্টেটমেন্টটি কল করার উপায়টি সংশোধন করার প্রয়োজন হতে পারে (সবচেয়ে খারাপ ক্ষেত্রে সম্ভবত আপনার এপিআই বা ডিবি স্তর কোনও ইনসার্টের কোনও মান প্রত্যাশা করবে না); এটি স্ট্যান্ডার্ড এসকিউএল নয় (কে চিন্তা করে); এটি পোস্টগ্র্যাস্কিল ৮.২ (ডিসেম্বর ২০০ ... ...) থেকে পাওয়া যায়
উপসংহার: আপনি যদি পারেন তবে 3 বিকল্পের জন্য যান se অন্য কোথাও, 1 টি পছন্দ করুন।
দ্রষ্টব্য: আপনি যদি বিশ্বব্যাপী সর্বশেষ idোকানো আইডিটি পেতে চান (তবে আপনার সেশন দ্বারা প্রয়োজনীয় নয়) এই সমস্ত পদ্ধতি অকেজো less এর জন্য, আপনাকে অবশ্যই অবলম্বন করতে হবে SELECT max(id) FROM table
(অবশ্যই, এটি অন্য লেনদেনের অনিয়ন্ত্রিত প্রবেশদ্বারগুলি পড়বে না)।
বিপরীতভাবে, আপনার বিবৃতি দিয়ে সদ্য তৈরি হওয়া আইডিটি পেতে আপনার উপরের 3 টি বিকল্পের পরিবর্তে কখনও ব্যবহার SELECT max(id) FROM table
করা উচিত নয়INSERT
, কারণ (পারফরম্যান্স বাদে) এটি একযোগে নিরাপদ নয়: আপনার INSERT
এবং আপনার SELECT
অন্য সেশনের মধ্যে অন্য কোনও রেকর্ড .োকানো থাকতে পারে।
SELECT max(id)
দুর্ভাগ্যক্রমে আপনি সারিগুলি মোছা শুরু করার সাথে সাথে কাজটি করেন না।
1,2,3,4,5
সারি থাকে এবং 4 এবং 5 টি সারি মুছে ফেলা হয় তবে সর্বশেষ ID োকানো আইডি 5 টি হলেও max()
ফিরে আসে
RETURNING id;
অন্য সারণিতে এটি sertোকাতে কীভাবে ব্যবহার করবেন তার একটি নমুনা স্বাগত হবে!
RETURNING id
খাওয়ানো কোনও এসকিউএল স্ক্রিপ্টের মধ্যে আমি কীভাবে ব্যবহার করতে পারি psql
?
INSERT বিবৃতিটির প্রত্যাবর্তনের ধারাটি দেখুন । মূলত, INSERT কোয়েরি হিসাবে দ্বিগুণ হয় এবং আপনাকে যে মানটি wasোকানো হয়েছিল তা ফিরিয়ে দেয়।
insert into names (firstname, lastname) values ('john', 'smith') returning id;
তবে এটি select id from names where id=$lastid
সরাসরি আইডিকে আউটপুট দেয় যেন আপনি সরাসরি দৌড়েছিলেন । যদি আপনি রিটার্নটিকে আ আ ভেরিয়েবেলে সংরক্ষণ করতে চান , তবে insert into names (firstname, lastname) values ('john', 'smith') returning id into other_variable;
যদি রিটার্নিং যুক্ত স্টেটমেন্টটি কোনও ফাংশনের সর্বশেষ বিবৃতি হয় , তবে returning
পুরোপুরি ফাংশন দ্বারা আইডি 'এড' প্রদান করা হয়।
আপনি নীচের মতোই INSERT বিবৃতিতে রিটার্নিং ক্লজটি ব্যবহার করতে পারেন
wgzhao=# create table foo(id int,name text);
CREATE TABLE
wgzhao=# insert into foo values(1,'wgzhao') returning id;
id
----
1
(1 row)
INSERT 0 1
wgzhao=# insert into foo values(3,'wgzhao') returning id;
id
----
3
(1 row)
INSERT 0 1
wgzhao=# create table bar(id serial,name text);
CREATE TABLE
wgzhao=# insert into bar(name) values('wgzhao') returning id;
id
----
1
(1 row)
INSERT 0 1
wgzhao=# insert into bar(name) values('wgzhao') returning id;
id
----
2
(1 row)
INSERT 0
লিওনব্লয়ের উত্তর বেশ সম্পূর্ণ। আমি কেবলমাত্র একটি বিশেষ ক্ষেত্রে যুক্ত করব যেখানে কোনও PL / pgSQL ফাংশন থেকে অপশন 3 হুবহু মাপসই করা হয় না যেখানেই শেষ সন্নিবেশিত মানটি পাওয়া দরকার।
উদাহরণস্বরূপ, আমাদের যদি নিম্নলিখিত সারণী থাকে:
CREATE TABLE person(
id serial,
lastname character varying (50),
firstname character varying (50),
CONSTRAINT person_pk PRIMARY KEY (id)
);
CREATE TABLE client (
id integer,
CONSTRAINT client_pk PRIMARY KEY (id),
CONSTRAINT fk_client_person FOREIGN KEY (id)
REFERENCES person (id) MATCH SIMPLE
);
আমাদের যদি ক্লায়েন্ট রেকর্ড সন্নিবেশ করতে হয় তবে আমাদের অবশ্যই একজন ব্যক্তির রেকর্ডটি উল্লেখ করতে হবে। তবে ধরা যাক আমরা একটি PL / pgSQL ফাংশন তৈরি করতে চাই যা ক্লায়েন্টে একটি নতুন রেকর্ড সন্নিবেশ করায় তবে নতুন ব্যক্তির রেকর্ড সন্নিবেশ করারও যত্ন নেয় of তার জন্য, আমাদের অবশ্যই লিওনব্লাইয়ের বিকল্প 3 এর সামান্য প্রকরণটি ব্যবহার করতে হবে:
INSERT INTO person(lastname, firstname)
VALUES (lastn, firstn)
RETURNING id INTO [new_variable];
নোট করুন যে দুটি INTO ধারা আছে। সুতরাং, পিএল / পিজিএসকিউএল ফাংশনটির সংজ্ঞা দেওয়া হবে:
CREATE OR REPLACE FUNCTION new_client(lastn character varying, firstn character varying)
RETURNS integer AS
$BODY$
DECLARE
v_id integer;
BEGIN
-- Inserts the new person record and retrieves the last inserted id
INSERT INTO person(lastname, firstname)
VALUES (lastn, firstn)
RETURNING id INTO v_id;
-- Inserts the new client and references the inserted person
INSERT INTO client(id) VALUES (v_id);
-- Return the new id so we can use it in a select clause or return the new id into the user application
RETURN v_id;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
এখন আমরা ব্যবহার করে নতুন ডেটা sertোকাতে পারি:
SELECT new_client('Smith', 'John');
অথবা
SELECT * FROM new_client('Smith', 'John');
এবং আমরা সদ্য নির্মিত আইডি পাই।
new_client
integer
----------
1
নীচের উদাহরণ দেখুন
CREATE TABLE users (
-- make the "id" column a primary key; this also creates
-- a UNIQUE constraint and a b+-tree index on the column
id SERIAL PRIMARY KEY,
name TEXT,
age INT4
);
INSERT INTO users (name, age) VALUES ('Mozart', 20);
তারপরে সর্বশেষ idোকানো আইডি পাওয়ার জন্য এটি সারণী "ব্যবহারকারী" সেক কলামের নাম "আইডি" ব্যবহার করুন
SELECT currval(pg_get_serial_sequence('users', 'id'));
SELECT CURRVAL(pg_get_serial_sequence('my_tbl_name','id_col_name'))
অবশ্যই আপনাকে অবশ্যই সারণীর নাম এবং কলামের নাম সরবরাহ করতে হবে।
এটি বর্তমান অধিবেশন / সংযোগের জন্য হবে http://www.postgresql.org/docs/8.3/static/function-sequence.html
এটা চেষ্টা কর:
select nextval('my_seq_name'); // Returns next value
যদি এই রিটার্নটি 1 (বা আপনার সিকোয়েন্সের শুরু_মূল্য যাই হোক না কেন), তবে মিথ্যা পতাকাটি পেরিয়ে ক্রমটিকে মূল মানটিতে পুনরায় সেট করুন:
select setval('my_seq_name', 1, false);
তা না হলে,
select setval('my_seq_name', nextValue - 1, true);
এটি সিক্যুয়েন্সের মানটি মূল অবস্থায় পুনরুদ্ধার করবে এবং "সেটওয়াল" আপনি যে সিকোয়েন্স মানটি সন্ধান করছেন তার সাথে ফিরে আসবে।
পোস্টগ্রিসের জন্য একই জন্য একটি ইনবিল্ট মেকানিজম রয়েছে, যা একই ক্যোয়ারিতে আইডি প্রদান করে বা আপনি যা চান ক্যোরিটি ফেরত চান। এখানে একটি উদাহরণ। আপনার একটি টেবিল তৈরি হয়েছে তা বিবেচনা করুন যাতে 2 কলাম কলাম 1 এবং কলাম 2 রয়েছে এবং আপনি প্রতিটি সন্নিবেশের পরে কলাম 1 ফিরিয়ে আনতে চান।
# create table users_table(id serial not null primary key, name character varying);
CREATE TABLE
#insert into users_table(name) VALUES ('Jon Snow') RETURNING id;
id
----
1
(1 row)
# insert into users_table(name) VALUES ('Arya Stark') RETURNING id;
id
----
2
(1 row)
জাভা এবং পোস্টগ্রিসের সাথে আমার এই সমস্যা ছিল। আমি একটি নতুন সংযোগকারী-জে সংস্করণ আপডেট করে এটি ঠিক করেছি।
PostgreSQL-9.2-1002.jdbc4.jar
https://jdbc.postgresql.org/download.html : সংস্করণ 42.2.12