আমি কি INSERT এর রিটার্ন মান ব্যবহার করতে পারি ... অন্য INSERT এ ফিরে আসছি?


87

এই সম্ভব ভালো কিছু হয়?

INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));

প্রথম টেবিলের রেফারেন্স সহ একটি দ্বিতীয় সারণীতে একটি সারি সন্নিবেশ করানোর জন্য মান হিসাবে প্রত্যাবর্তন মানটি ব্যবহার করার মতো?

উত্তর:


106

আপনি পোস্টগ্রিস 9.1 দিয়ে শুরু করে এটি করতে পারেন:

with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val)
SELECT id
FROM rows

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

create function t1_ins_into_t2()
  returns trigger
as $$
begin
  insert into table2 (val) values (new.id);
  return new;
end;
$$ language plpgsql;

create trigger t1_ins_into_t2
  after insert on table1
for each row
execute procedure t1_ins_into_t2();

4
রিটার্নিং আইডির পাশে কীভাবে মান সন্নিবেশ করা যায়? উদাহরণস্বরূপ: ট্যাবলেট 2 (ভাল 1, ভাল 2, ভাল 3) অন্তর্ভুক্ত করুন (1, 2, সারি থেকে আইডি নির্বাচন করুন)
মাহমুদ হানাফি

@ মাহমুদহানাফি: এর সাথে প্রতিস্থাপন rowsকরা (some_query returning ...)আজকাল কাজ করতে পারে (চেষ্টা করেনি)।
ডেনিস ডি বার্নার্ডি

4
@ মাহমুদহানাফি: রিটার্নিং আইডির পাশের মানগুলি সন্নিবেশ করানোর জন্য আপনি এই জাতীয় কিছু করতে পারেন: সারণি থেকে ট্যাবলেট 2 (ভাল 1, ভাল 2, ভাল 3) নির্বাচন করুন আইডি, 1, 2 সারি থেকে
ভিন্দি

upvated! এই পারমাণবিক অর্থ যদি প্রথম সন্নিবেশ সফল হয় এবং দ্বিতীয়টি না ঘটে তবে কী ঘটে?
পাইরেটএপ

4
@ পাইরেট অ্যাপ সবেমাত্র পরীক্ষিত! v12.4। দ্বিতীয়টি ব্যর্থ হলে প্রথম INSERT অবশ্যই রোল-ব্যাকড, তবে প্রথম INSERT এর ধারাবাহিকতা / স্ব-স্বীকৃতি বাদ দেওয়া হয়
ম্যাডাকল

58

এই পরিস্থিতির জন্য সেরা অনুশীলন। ব্যবহার RETURNING … INTO

INSERT INTO teams VALUES (...) RETURNING id INTO last_id;

নোট করুন এটি PLPGSQL এর জন্য


4
এটা আসলে কি জিনিস? আপনি যে ডকটির সাথে লিঙ্ক করেছেন তার কোনও অংশই উল্লেখ করার মতো বলে মনে হচ্ছে না RETURNING ... INTO
অ্যালেক


@ পেড্রোড: এটি করে।
বার্ট হফল্যান্ড

13

ডেনিস ডি বার্নার্ডির দেওয়া উত্তরের সাথে তাল মিলিয়ে ..

আপনি যদি পরে আইডি ফেরত চান এবং টেবিল 2 এ আরও জিনিস inোকাতে চান তবে:

with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val, val2, val3)
SELECT id, 'val2value', 'val3value'
FROM rows
RETURNING val

10
DO $$
DECLARE tableId integer;
BEGIN
  INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id INTO tableId;
  INSERT INTO Table2 (val) VALUES (tableId);
END $$;

পিএসকিএল (10.3, সার্ভার 9.6.8) দিয়ে পরীক্ষিত


8

আপনি lastval()ফাংশনটি ব্যবহার করতে পারেন :

যে nextvalকোনও সিকোয়েন্সের জন্য সর্বাধিক পাওয়া রিটার্ন মান

সুতরাং এর মতো কিছু:

INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val)  VALUES (lastval());

এটি যতক্ষণ না nextval()আপনার INSERTs এর মধ্যে অন্য কোনও সিক্যুয়েন্সে (বর্তমান সেশনে) কল না করে ততক্ষণ তা কাজ করবে ।

হিসাবে ডেনিস নিচে উল্লেখ করা এবং আমি সম্পর্কে উপরে সতর্ক ব্যবহার lastval()যদি অন্য ক্রম ব্যবহার অ্যাক্সেস করা হয় কষ্ট আপনি পেতে পারেন nextval()আপনার টিপে মধ্যে। যদি Table1ম্যানুয়ালি nextval()কোনও সিকোয়েন্সে ডেকে আনা হয় বা যদি সম্ভবত একটি প্রাথমিক SERIALবাBIGSERIAL কী দিয়ে টেবিলে একটি INSERT করে থাকে তবে এটি ঘটতে পারে । আপনি যদি সত্যই বেহাল হয়ে উঠতে চান (একটি ভাল জিনিস, তারা আপনাকে সত্যিকার অর্থেই আপনাকে পেয়ে currval()যাবেন ), তবে আপনি ব্যবহার করতে পারেন তবে আপনাকে প্রাসঙ্গিক ক্রমের নামটি জানতে হবে:

INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val)  VALUES (currval('Table1_id_seq'::regclass));

স্বয়ংক্রিয়ভাবে উত্পাদিত ক্রমটি সাধারণত নামকরণ করা হয় t_c_seqযেখানে tটেবিলের নাম এবং cকলামের নাম তবে আপনি সর্বদা প্রবেশ করে psqlএবং এটি বলে খুঁজে পেতে পারেন :

=> \d table_name;

এবং তারপরে প্রশ্নের মধ্যে থাকা কলামটির জন্য ডিফল্ট মানটি দেখুন:

id | integer | not null default nextval('people_id_seq'::regclass)

এফওয়াইআই: lastval()কমবেশি, মাইএসকিউএল-র পোস্টগ্রিএসকিউএল সংস্করণ LAST_INSERT_ID। আমি কেবল এটি উল্লেখ করেছি কারণ পোস্টগ্র্রেএসকিউএল এর চেয়ে অনেক লোক মাইএসকিউএল এর সাথে বেশি পরিচিত তাই পরিচিত কোনও lastval()জিনিসের সাথে লিঙ্ক করা জিনিসগুলি স্পষ্ট করতে পারে।


4
আরও ভাল ব্যবহার কার্ভাল (), যদিও টেবিল 1 তে একটি ট্রিগার পরবর্তী সন্নিবেশগুলি করে।
ডেনিস ডি বার্নার্ডি

@ ডেনিস: সত্য, তবে তারপরে আপনার ক্রমটির নাম প্রয়োজন। আমি কেবল সমস্ত ঘাঁটি কভার করার জন্য সেই প্রভাবটিতে সামান্য আপডেট যুক্ত করব।
মিউ

লাস্টভাল () এবং কার্ভাল () উভয়ই অন্যান্য সংযোগের জন্য নয়, বর্তমান ডাটাবেস সংযোগের জন্য কাজ করে। অন্যান্য ব্যবহারকারীরা একই সময়ে ক্রমটি আপডেট করতে পারে, এটি আপনার ফলাফল পরিবর্তন করবে না। অন্যদের সম্পর্কে চিন্তা করবেন না, তারা কখনও আপনার ফলাফলগুলি লাস্টভাল এবং / কার্ভাল এর পরিবর্তিত করবে না। কোনও ট্রান্সঅ্যাকশন ছাড়া কানেকশনপুল ব্যবহার করার সময় লাস্টভাল এবং কার্ভাল মোটেই ব্যবহার করা যায় না, যখন জিনিসগুলি ভুল হয়ে যায়: আপনি ডাটাবেস সংযোগ নিয়ন্ত্রণ করেন না।
ফ্রাঙ্ক হিকেন্স

4
@ ফ্র্যাঙ্ক: হ্যাঁ, তারা সমস্ত সেশন নির্দিষ্ট, তবে সমস্যাটি lastvalহ'ল টেবিল 1-এর একটি আফটার ইনসার্ট ট্রিগার থেকে আপনার পিছনে পিছনে ইনসার্ট ভিত্তিক একটি ক্রম থাকতে পারে। এটি বর্তমান অধিবেশনে থাকবে এবং সম্ভবত lastval()আপনি যখন এটি প্রত্যাশা করবেন না তখন পরিবর্তন হবে।
মিউ খুব ছোট

1

টেবিল_এক্স

পরের আইডি ডিফল্ট ('টেবিল_আইডি_সেক' :: রেগক্লাস),

ক্যাম্প 1 ভারচার

ক্যাম্প 2 ভারচার

INSERT INTO table_ex(camp1,camp2) VALUES ('xxx','123') RETURNING id 
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.