এসকিউএল সার্ভার - INSERT এর পরে ফেরতের মান


318

আমি ইনসার্ট-স্টেটমেন্টের পরে কী-মানটি ফিরে পাওয়ার চেষ্টা করছি। উদাহরণ: বৈশিষ্ট্যগুলির নাম এবং আইডি সহ আমি একটি টেবিল পেয়েছি। আইডি একটি উত্পন্ন মান।

    INSERT INTO table (name) VALUES('bob');

এখন আমি একই পদক্ষেপে আইডিটি ফিরে পেতে চাই। এটি কিভাবে হয়?

আমরা মাইক্রোসফ্ট এসকিউএল সার্ভার ২০০৮ ব্যবহার করছি।


আমি এখানে একটি দরকারী উত্তর খুঁজে পেয়েছি: [স্টেট-ওভার-স্টেটমেন্ট-রিটার্ন-জেনারেটেড-কীগুলি] [1] [1]: স্ট্যাকওভারফ্লো
লার্স লাডেগার্ড

উত্তর:


477

আলাদা আলাদা নির্বাচন করার দরকার নেই ...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

এটি অ-পরিচয় কলামগুলির জন্যও কাজ করে (যেমন জিইউআইডি)


29
আপনি কিছুটা ব্যাখ্যা করতে পারেন? এই উদাহরণে আউটপুট কোথায় যায়? ডকুমেন্টেশনটি কেবল টেবিলগুলির জন্য উদাহরণ দেখায় (আউটপুট ব্যবহার করে ... এতে)। আদর্শভাবে আমি এটিকে কেবল একটি ভেরিয়েবলে স্থান দিতে সক্ষম হতে চাই
জনিআআআআ

2
@ জনিলিডস: আপনি এটি কোনও ভেরিয়েবলের সাথে করতে পারবেন না (যদি কোনও টেবিলের পরিবর্তনশীল না হয়)। OUTPUT ক্লায়েন্ট বা একটি টেবিলে যায়
gbn

7
দুর্ভাগ্যক্রমে, আপনি এই উপর নির্ভর করতে পারবেন না কারণ টেবিলে একটি ট্রিগার যুক্ত করা আপনার বক্তব্যগুলিকে ভেঙে দেবে! পুনঃ ব্লগস.এমএসডন.কম
বিএসএইচএলপিগ্রোম্ম্যাবিলিটি

1
@ হাজিকেলিস্ট: এটি বেশ প্রান্তের একটি মামলা, ট্রিগারটিতে সাধারণত চালিয়ে যাওয়া সহায়তা করে। দেখুন stackoverflow.com/questions/1483732/set-nocount-on-usage
gbn

5
কখনই @@ পরিচয় ব্যবহার করবেন না। SCOPE_IDENTITY, হ্যাঁ, তবে কখনই @@ পরিচয়। এটি অবিশ্বাস্য
জিবিএন

188

SCOPE_IDENTITY()নতুন আইডি মান পেতে ব্যবহার করুন

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http://msdn.microsoft.com/en-us/library/ms190315.aspx


7
ধরে নেওয়া idহচ্ছে পরিচয়
Ilia G

12
@ liho1eye - ওপি পরিচয় কলামের নাম হিসাবে উল্লেখ করেছে id, তাই হ্যাঁ।
কর্ট

3
বৃহত্তর সিস্টেমে, যদি একই সাথে অনেকগুলি স্কল চালানো হয়? এটি কি প্রতিটি অনুরোধে শেষ sertedোকানো আইডি ফিরিয়ে দেবে?
শিব

2
@ শিভ "এসসিওপিআইডিআইএনটিটি কেবল বর্তমান সুযোগের মধ্যে সন্নিবেশিত মানগুলি ফেরত দেয়"
গুডিজ

45
INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

সবচেয়ে নিরাপদ বাজি যেহেতু ট্রিগারগুলির সাথে টেবিলগুলিতে OUTPUT ক্লজ বিরোধের সাথে একটি জ্ঞাত সমস্যা রয়েছে। এটিকে একেবারেই অবিশ্বাস্য করে তোলে যদিও আপনার টেবিলটিতে বর্তমানে কোনও ট্রিগার নেই - লাইনটির নিচে কেউ যুক্ত করা আপনার অ্যাপ্লিকেশনটি ভেঙে দেবে। টাইম বোম্বের আচরণ

গভীর ব্যাখ্যার জন্য এমএসডিএন নিবন্ধটি দেখুন:

http://blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx


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

এটি আমাদের লিগ্যাসি পরিবেশের জন্য কোনও বিকল্প নয় @gbn
হাজিকলিস্ট

@ হাইজাইলিস্ট আমাদের সবার উত্তরাধিকার রয়েছে তবে OUTPUT আপকে জবাবদিহি করার ঝুঁকি কম, এটি যা গ্রহণ করে তা হ'ল অনাকাউন্ট। যদি কেউ ট্রিগার যোগ করছে তবে তাদের কীভাবে কোডিং করা উচিত তা বোঝা উচিত (বোঝায় আপনার মূল নিয়ন্ত্রণ রয়েছে), অথবা আপনার বিকাশকারীদের প্রশিক্ষণ দেওয়া দরকার some কিছু সময় আপনি যখন এসকিউএলের সেই সংস্করণটি আর থাকবেন না তখন আপনাকে স্থানান্তর করতে বাধ্য করা হবে সমর্থিত ইত্যাদি তাই ট্রিগারগুলির ফলে ফলাফলের কারণ হয় না। যাই হোক না কেন, এটা সবচেয়ে ভালো উত্তর আপনি যদি এর পরিবর্তে ট্রিগারের আছে যদি কারণ নয় SCOPE_IDENTITY নাও করতে পারে কাজ ( stackoverflow.com/questions/908257/... )
gbn

@gbn - আমি এই জাতীয় মূর্খ বিষয়গুলি এড়াতে চাই। আমি আমার সমস্ত বিকাশকারীকে বলতে যাচ্ছি না, "প্রতিটি ট্রিগারটিতে 'আমার অ্যাপ্লিকেশন বিবৃতি ভাঙবেন না' যুক্ত করতে ভুলবেন না।" - তুমি এটা রাখতে পারো. "পরিবর্তে" দৃশ্যাবলী ইমো ইমোয়ের চেয়ে অনেক বেশি।
হাইজিকেলিস্ট 16:39

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

33

সত্তা ফ্রেমওয়ার্ক জিবিএন এর উত্তরের অনুরূপ কিছু সম্পাদন করে:

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');

SELECT t.[CustomerID]
FROM @generated_keys AS g 
   JOIN dbo.Customers AS t 
   ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0

আউটপুট ফলাফলগুলি একটি অস্থায়ী টেবিল ভেরিয়েবলে সংরক্ষণ করা হয় এবং তারপরে ক্লায়েন্টের কাছে আবার নির্বাচন করা হয়। গোটচা সম্পর্কে সচেতন হতে হবে:

সন্নিবেশগুলি একাধিক সারি তৈরি করতে পারে, সুতরাং ভেরিয়েবল একাধিক সারি ধরে রাখতে পারে, তাই আপনাকে একের বেশি ফেরত দেওয়া যেতে পারে ID

আমার কোনও ধারণা নেই কেন ইএফ অভ্যন্তরীণ ছকে টেবিলের সাথে আসল টেবিলে ফিরে আসবে (কোন পরিস্থিতিতে দু'জন মিলে না।

তবে ইএফ এটি করে।

এসকিউএল সার্ভার ২০০৮ বা কেবলমাত্র নতুন। যদি এটি 2005 হয় তবে আপনার ভাগ্যের বাইরে।


2
ইএফ এটির কারণ এটি নিশ্চিত করা হয় যে এটি itোকানো Customerরেকর্ডে অন্যান্য সমস্ত পরিবর্তনগুলি "দেখতে" পারে, যেমন এটির অন্যান্য ডিবি-পার্শ্ব যুক্তিও প্রভাবিত করতে পারে, যেমন DEFAULTকিছু কলামে, টেবিলের উপর ট্রিগার ইত্যাদি। EF আপডেট করে সন্নিবেশ (বস্তু) এটি সন্নিবেশের জন্য ব্যবহার করে, তাই ক্লায়েন্টের পক্ষ গ্রাহক আইডির সাথে এবং সারির বর্তমান অবস্থার প্রতিনিধিত্ব করে সমস্ত কিছু পেয়ে যায়।
হিলারিয়ন

ইএফ ব্যবহার না করার আরেকটি কারণ।
cscwg

11

@@IDENTITY একটি সিস্টেম ফাংশন যা সর্বশেষে সন্নিবেশিত পরিচয় মানটি দেয়।


4
@@ পরিচয় ব্যবহারের বিরুদ্ধে সর্বদা পরামর্শ দিতে হবে - এটি সঠিক (খুব বেশি বিস্তৃত) অনেক কম থ্রেড-নিরাপদ নয় - দয়া করে এসসিপিপিআইডিএনটিএটি সম্পর্কে কর্টের উত্তর দেখুন ()।
zanlok

এটি থ্রেড মোটেই নিরাপদ নয়।
cscwg

10

Sertোকানোর পরে প্রস্থান করার অনেক উপায় আছে

আপনি যখন কোনও টেবিলের মধ্যে ডেটা .োকান, আপনি টেবিলে সন্নিবেশ করা হয়েছে এমন একটি অনুলিপি ফিরিয়ে দিতে OUTPUT ধারাটি ব্যবহার করতে পারেন। OUTPUT ধারাটি দুটি মূল ফর্ম গ্রহণ করে: OUTPUT এবং আউটপুট INTO। আপনি যদি কলিং অ্যাপ্লিকেশনটিতে ডেটা ফিরিয়ে দিতে চান তবে OUTPUT ফর্মটি ব্যবহার করুন। আপনি যদি কোনও টেবিল বা কোনও টেবিলের পরিবর্তনশীলতে ডেটা ফিরিয়ে দিতে চান তবে আউটপুট INTO ফর্মটি ব্যবহার করুন।

DECLARE @MyTableVar TABLE (id INT,NAME NVARCHAR(50));

INSERT INTO tableName
(
  NAME,....
)OUTPUT INSERTED.id,INSERTED.Name INTO @MyTableVar
VALUES
(
   'test',...
)

IDENT_CURRENT : এটি কোনও নির্দিষ্ট টেবিল বা কোনও সেশনে দেখার জন্য নির্মিত সর্বশেষ পরিচয় দেয়।

SELECT IDENT_CURRENT('tableName') AS [IDENT_CURRENT]

এসকোপিআইডিএনটিটি : এটি একই অধিবেশন এবং একই সুযোগ থেকে শেষ পরিচয় দেয়। একটি সুযোগ একটি সঞ্চিত পদ্ধতি / ট্রিগার ইত্যাদি is

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];  

@@ পরিচয়: এটি একই সেশন থেকে শেষ পরিচয় দেয়।

SELECT @@IDENTITY AS [@@IDENTITY];

আমি আউটপুট ইনটো চেষ্টা করেছিলাম, তবে এটি খুব ধীর।
cscwg

1
@RezaJenabi জুন, আউট করা খুব ভাল কাজ করা হয়, ভাল চেয়ে টেবিল অনেক ID খুঁজে নেই। আমি এর out putজন্য ব্যবহার করে bulk insertsertোকাতাম select statement। আপনার পরামর্শটি ধন্যবাদ
আমিরহোসেইন

5

সবচেয়ে ভাল এবং সুনিশ্চিত সমাধানটি ব্যবহার করা হচ্ছে SCOPE_IDENTITY()

প্রতিটি সন্নিবেশের পরে আপনাকে স্কোপ পরিচয় পেতে হবে এবং এটি একটি ভেরিয়েবলে সংরক্ষণ করতে হবে কারণ আপনি একই স্কোপটিতে দুটি সন্নিবেশ কল করতে পারেন।

ident_currentএবং @@identityতারা কাজ করতে পারে তবে সেগুলি নিরাপদ সুযোগ নয়। আপনার বড় অ্যাপ্লিকেশনটিতে সমস্যা থাকতে পারে

  declare @duplicataId int
  select @duplicataId =   (SELECT SCOPE_IDENTITY())

আরও বিশদ এখানে মাইক্রোসফ্ট ডক্স


1
এটিকে সহজতর করতে পারেselect @duplicataId = SCOPE_IDENTITY()
pcnate

1
OUTPUTধারাটি একটি আরও ভাল, আরও বিশুদ্ধ সমাধান :)
ডেল কে

আউটপুট ইনটো খুব ধীর।
cscwg

4

আপনি scope_identity()সবেমাত্র একটি ভেরিয়েবলের মধ্যে সন্নিবেশ করানো সারির আইডি নির্বাচন করতে ব্যবহার করতে পারেন তবে সেই টেবিল থেকে আপনি যে কলামটি চান তা নির্বাচন করুন যেখানে আইডি = আপনি যে পরিচয়টি পেয়েছেনscope_identity()

এমএসডিএন তথ্যের জন্য এখানে দেখুন http://msdn.microsoft.com/en-us/library/ms190315.aspx


1

সন্নিবেশ কমান্ডের পরে সর্বশেষ sertedোকানো আইডি পাওয়ার একাধিক উপায় রয়েছে।

  1. @@IDENTITY : এটি বর্তমান সেশনে একটি সংযোগে উত্পন্ন শেষ পরিচয় মানটি দেয়, সারণী এবং বিবরণের সুযোগ নির্বিশেষে যে মানটি উত্পন্ন করে
  2. SCOPE_IDENTITY(): এটি সারণী নির্বিশেষে বর্তমান সংযোগের বর্তমান স্কোপে সন্নিবেশ বিবৃতি দ্বারা উত্পন্ন সর্বশেষ পরিচয় মানটি প্রদান করে।
  3. IDENT_CURRENT(‘TABLENAME’): এটি কোনও সংযোগ, অধিবেশন বা সুযোগ নির্বিশেষে নির্দিষ্ট টেবিলে উত্পন্ন শেষ পরিচয় মানটি প্রদান করে। IDENT_CURRENT স্কোপ এবং সেশনের মাধ্যমে সীমাবদ্ধ নয়; এটি একটি নির্দিষ্ট টেবিলের মধ্যে সীমাবদ্ধ।

এখন আমার প্রয়োজনের সাথে কোনটি সঠিক ম্যাচ হবে তা সিদ্ধান্ত নেওয়া আরও কঠিন বলে মনে হচ্ছে।

আমি বেশিরভাগই SCOPE_IDENTITY () পছন্দ করি।

আপনি যদি সারণি নাম সন্নিবেশ বিবৃতি সহ টেবিলনামের সাথে SCOPE_IDENTITY () নির্বাচন করেন তবে আপনি প্রত্যাশা অনুযায়ী সঠিক ফলাফল পাবেন।

সূত্র: কোডোবি


0

এসকিউএল সার্ভারে পরিচয় কলাম হিসাবে আইডি ব্যবহার করে এমন কোনও টেবিলটি সন্নিবেশ করার সময় আমি এইভাবে আউটপুট সংযুক্তি ব্যবহার করি:

'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)

0

আপনি আপনার সন্নিবেশ বিবৃতিতে একটি নির্বাচিত বিবৃতি যুক্ত করতে পারেন। পূর্ণসংখ্যা myInt = টেবিল 1 (FName) মানগুলিতে'োকান ('ফ্রেড'); Scope_Identity () নির্বাচন করুন; মৃত্যুদন্ড কার্যকর করা হলে এটি পরিচয়ের একটি মান ফেরত দেবে।


-4

একটি পরিচয় কলাম সহ একটি সারণিতে একটি সন্নিবেশ করার পরে, আপনি মানটি পেতে @@ পরিচয় উল্লেখ করতে পারেন: http : //msdn.mic Microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx


24
কখনই @@ পরিচয় ব্যবহার করবেন না: এটি স্কোপটি নিরাপদ নয়: ট্রিগার ইত্যাদি প্রভাবিত করে।
gbn

-4

* সংযোগ স্ট্রিংয়ে প্যারামিটার ক্রম কখনও কখনও গুরুত্বপূর্ণ। * সরবরাহকারী প্যারামিটারের অবস্থানটি একটি সারি যুক্ত করার পরে রেকর্ডসেট কার্সারটিকে ভেঙে ফেলতে পারে। এসকিউএলএলডিডি সরবরাহকারীর সাথে আমরা এই আচরণটি দেখেছি।

একটি সারি যুক্ত হওয়ার পরে, সারি ক্ষেত্রগুলি উপলভ্য নয়, সরবরাহকারী সংযোগ স্ট্রিংয়ের প্রথম পরামিতি হিসাবে নির্দিষ্ট করা হবে । সরবরাহকারীর প্রথম প্যারামিটার বাদে সংযোগ স্ট্রিংয়ের যে কোনও জায়গায় থাকা সত্ত্বেও সদ্য সন্নিবেশ করা সারি ক্ষেত্রগুলি উপলভ্য নয়। যখন আমরা সরবরাহকারীটিকে প্রথম প্যারামিটারে স্থানান্তরিত করি তখন সারি ক্ষেত্রগুলি যাদুতে উপস্থিত হয়।


1
আপনি কি আমাদের বলতে পারবেন যে এই মন্তব্যটি কীভাবে জিজ্ঞাসা করা প্রশ্নটির সাথে সম্পর্কিত / প্রাসঙ্গিক? আমি এটি ক্যাপ / সাহসী প্রাপ্য মনে করি না। যদি আপনার উত্তরটি সহায়ক হিসাবে বিবেচিত হয়, ব্যবহারকারীরা এটিতে ভোট দেবেন।
n__o

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

আপনার উত্তরটি সম্পাদনা করতে হবে এবং উন্নত করতে হবে। এটি বর্তমানে শোরগোল এবং একটি উত্তম উত্তর বা এমনকি চেষ্টা হিসাবে আসে না
জেমস

"গোলমাল" বলতে আসলে কী বোঝ? আপনার নিজের অভিযোগটি ব্যাখ্যা করা দরকার। এটি যতটা সহজ হতে পারে। আপনি যদি আপনার সংযোগ স্ট্রিংয়ের প্যারামিটারগুলির ক্রম পরিবর্তন করেন তবে এটি সন্নিবেশের পরে সারি ডেটা উপলব্ধ কিনা তা প্রভাবিত করতে পারে।
ডেভিড গাইডস 21
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.