কোনও ছকে শেষ পরিচয় inোকানোর সর্বোত্তম উপায়


35

কোন সন্নিবেশের মাধ্যমে সবেমাত্র উত্পন্ন পরিচয় মানটি পাওয়া যায় তার মধ্যে সেরা বিকল্পটি কোনটি? পারফরম্যান্সের বিচারে এই বিবৃতিগুলির প্রভাব কী?

  1. SCOPE_IDENTITY()
  2. সমষ্টিগত ফাংশন MAX()
  3. TOP 1টেবিলনাম থেকে পরিচয় কলামটি নির্বাচন করুনORDER BY IdentityColumn DESC

1
ব্যবহারের PostgreSQL এবং আপনার বালুচর থেকে এটা থাকবে postgresql.org/docs/9.1/static/sql-insert.html
ইয়েভগেনি Afanasyev

বামফিল্ড বিকল্প - যদি আপনার টেবিলে একটি গাইড কলাম থাকে এবং সন্নিবেশকালে আপনি একটি নতুন গাইড তৈরি করতে এবং এটি নতুন কলামে সন্নিবেশ করতে পারেন - তারপরে উত্পন্ন উত্স সনাক্তকরণটি বের করার জন্য আপনি সেই গাইডের সাথে সারিটি নির্বাচন করতে পারেন।
নিকো

উত্তর:


56

SCOPE_IDENTITY()আপনি যদি একটি একক সারি সন্নিবেশ করিয়ে থাকেন এবং উত্পন্ন আইডিটি পুনরুদ্ধার করতে চান তবে ব্যবহার করুন

CREATE TABLE #a(identity_column INT IDENTITY(1,1), x CHAR(1));

INSERT #a(x) VALUES('a');

SELECT SCOPE_IDENTITY();

ফলাফল:

----
1

OUTPUTআপনি যদি একাধিক সারি সন্নিবেশ করিয়ে থাকেন এবং উত্পন্ন আইডির সেটটি পুনরুদ্ধার করতে চান তবে এই ধারাটি ব্যবহার করুন

INSERT #a(x) 
  OUTPUT inserted.identity_column 
  VALUES('b'),('c');

ফলাফল:

----
2
3

এবং কেন এটি সেরা দ্রুত বিকল্প?

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

নির্ভুলতার দিকটি উপেক্ষা করা সেই মেইলম্যানকে বলা যেমন তিনি আজকের মেইল ​​সরবরাহ করার জন্য একটি ভাল কাজ করেছেন - তিনি তার গড় সময়ের চেয়ে 10 মিনিট দ্রুত গতিতে যাত্রা শেষ করেছেন, সমস্যাটি হ'ল মেলটির কোনওটিই সঠিক বাড়িতে পৌঁছে দেওয়া হয়নি।

নিম্নলিখিত কোনও ব্যবহার করবেন না :

  • @@IDENTITY - যেহেতু এটি সমস্ত পরিস্থিতিতে ব্যবহার করা যায় না, উদাহরণস্বরূপ যখন একটি পরিচয় কলাম সহ একটি টেবিলের একটি ট্রিগার থাকে যা তার নিজস্ব পরিচয় কলাম সহ অন্য টেবিলে সন্নিবেশ করায় - আপনি ভুল মানটি ফিরে পাবেন।
  • IDENT_CURRENT()- আমি এখানে এ সম্পর্কে বিশদে যাচ্ছি , এবং মন্তব্যগুলি দরকারী পঠনও দরকারী, তবে মূলত, সম্মতিতে, আপনি প্রায়শই ভুল উত্তর পেয়ে যাবেন।
  • MAX()বা TOP 1- আপনাকে দুটি বিবৃতি সিরিয়ালাইজযোগ্য বিচ্ছিন্নতার সাথে সুরক্ষিত করতে হবে যাতে আপনি যে MAX()বিষয়টি পেয়েছেন তা অন্য কারও নয়। এটি কেবল ব্যবহারের চেয়ে অনেক বেশি ব্যয়বহুল SCOPE_IDENTITY()

আপনি যখন দুটি বা ততোধিক সারি সন্নিবেশ করান তখনই এই ফাংশনগুলি ব্যর্থ হয় এবং উত্পন্ন সমস্ত পরিচয় মান প্রয়োজন - ক্লজটিই আপনার একমাত্র বিকল্প OUTPUT


আমার স্মৃতিতে আর একটি প্রশ্ন ট্রিগার করে। যখনই কোনও নির্দিষ্ট সারণী বা ব্যবহারকারীর দ্বারা নির্দিষ্ট টেবিলে শেষ পরিচয় উত্পন্ন করার দরকার হয় তখনই সেই কলামটির একমাত্র সঠিক এবং সর্বোত্তম উপায়?
এএএসসি

কীভাবে আমি যখন কোনও টেবিলে একাধিক সারি সন্নিবেশ করবো তখন SCOPE_IDENTITY () সর্বদা শেষ উত্পন্ন পরিচয়টি ফিরিয়ে দেবে? কলাম যদি প্রাথমিক কী হয় তবে পরিচয় কলাম নয়?
এএএসসি

@ এএএসসি হ্যাঁ, এটি সর্বশেষটি ফিরে আসবে। এটি কোনও পরিচয় কলাম না হলে, না, এই ফাংশনগুলির কোনওটিই কাজ করবে না। সেক্ষেত্রে পিকে মানটি কোথা থেকে আসে?
অ্যারন বারট্র্যান্ড

আমি এটি আমাদের অ্যাপ্লিকেশনের একটি কলামের জন্য দেখেছি যেখানে কলামটি INT প্রকারের, এবং বিকাশকারীরা যখনই কোনও নতুন রেকর্ড সন্নিবেশ করানোর প্রয়োজন হয় তখন ম্যাক্স (কলামের নাম) +1 ব্যবহার করেন
এএএসসি

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

7

পারফরম্যান্স বাদে, তাদের সবারই আলাদা অর্থ রয়েছে।

SCOPE_IDENTITY()বর্তমান স্কোপের মধ্যে সরাসরি কোনও টেবিলে সন্নিবেশিত সর্বশেষ পরিচয় মান দেবে (স্কোপ = ব্যাচ, সঞ্চিত পদ্ধতি ইত্যাদি) তবে এর মধ্যে নয়, বলুন, এমন একটি ট্রিগার যা বর্তমান সুযোগ দ্বারা বরখাস্ত করা হয়েছিল)।

IDENT_CURRENT()কোনও ব্যবহারকারীর দ্বারা যে কোনও সুযোগ থেকে নির্দিষ্ট সারণিতে সন্নিবেশিত শেষ পরিচয় মানটি আপনাকে দেবে ।

@@IDENTITYসারণী বা সুযোগ নির্বিশেষে বর্তমান সংযোগের জন্য সর্বাধিক সাম্প্রতিক INSERT বিবৃতি দ্বারা উত্পন্ন সর্বশেষ পরিচয় মান দেয়। (পার্শ্ব দ্রষ্টব্য: অ্যাক্সেস এই ফাংশনটি ব্যবহার করে এবং এতে ট্রিগারগুলির সাথে কিছু সমস্যা রয়েছে যা সনাক্তকরণ কলামগুলির সাথে সারণিতে মান সন্নিবেশ করে))

টেবিলটির নেতিবাচক পরিচয় পদক্ষেপ থাকলে বা খেলায় সারি সন্নিবেশ করা থাকলে ব্যবহার MAX()বা TOP 1আপনাকে সম্পূর্ণ ভুল ফলাফল দিতে SET IDENTITY_INSERTপারে। এই সমস্ত প্রদর্শিত একটি স্ক্রিপ্ট এখানে:

CREATE TABLE ReverseIdent (
    id int IDENTITY(9000,-1) NOT NULL PRIMARY KEY CLUSTERED,
    data char(4)
)

INSERT INTO ReverseIdent (data)
VALUES ('a'), ('b'), ('c')

SELECT * FROM ReverseIdent

SELECT IDENT_CURRENT('ReverseIdent') --8998
SELECT MAX(id) FROM ReverseIdent --9000

SET IDENTITY_INSERT ReverseIdent ON

INSERT INTO ReverseIdent (id, data)
VALUES (9005, 'd')

SET IDENTITY_INSERT ReverseIdent OFF

SELECT IDENT_CURRENT('ReverseIdent') --8998
SELECT MAX(id) FROM ReverseIdent --9005

সারাংশ: দিয়ে বিদ্ধ SCOPE_IDENTITY(), IDENT_CURRENT()অথবা @@IDENTITY, এবং নিশ্চিত করুন যে আপনি যে এক রিটার্ন আপনি আসলে প্রয়োজন ব্যবহার করছেন।


1
আপনি কেন নিজের ব্যবহারের উত্সাহ দেন IDENT_CURRENT()এবং @@IDENTITYযখন আপনার নিজস্ব স্ক্রিপ্ট দেখায় যে সেগুলি ভুল ফলাফল আউটপুট দেয়?
অ্যারন বার্ট্র্যান্ড

1
অ্যারোনবার্ট্র্যান্ড আমি নিশ্চিত না যে আমি অনুসরণ করি। উত্পাদিত সর্বশেষ পরিচয় মান ছিল 8998 (ধাপটি -1 দেখুন) এবং এটাই IDENT_CURRENT()প্রত্যাবর্তন করে। ম্যাক্স () কখনই প্রথম সারির বাইরে সঠিক মান দেয় না, যেহেতু আইডি পিছনের দিকে গণনা করা হয়, এবং এটি দিয়ে IDENTITY_INSERT9005 একটি উত্পন্ন পরিচয় মান হয় না, এটি দ্বারা প্রতিফলিত হয় না IDENT_CURRENT()। আপনি যদি সত্যিই যা ফেরান তা যদি হয় তবে এটি "ভুল" ফলাফলগুলি দেখতে পারেSCOPE_IDENTITY() । কাজের জন্য সঠিক সরঞ্জামটি চয়ন করুন।
db2

ওপিটি inোকানো পরিচয় মান হওয়ার পরে বলে মনে হচ্ছে - এই ক্ষেত্রে 8998 টি ভুল। আপনি উল্লিখিত প্রান্তের মামলাগুলি (পিছনের দিকের বর্ধন এবং আইডিএনটিআইটিএসএসআরটি চালু) এমনকি আমার মতে IDENT_CURRENT ব্যবহার করার বিরুদ্ধে যুক্তি দেয় এবং @@ পরিচয়টি সত্যিকার অর্থে ট্রিগারগুলির বিপদের কারণে (এখন বা পরে যুক্ত হওয়া) ব্যবহার করা উচিত নয়। আমি এখনও বুঝতে চেষ্টা করে যাচ্ছি যে কেন আইপিআইসিআরইএনএনটি হ'ল ওপি ব্যবহার করতে চাইবে (বিশেষত সম্মতিতে) বা যখন আরও অনেক নির্ভরযোগ্য পদ্ধতি বিদ্যমান থাকে তখন কেন @@ পরিচয়টি যে কেউ ব্যবহার করবেন।
অ্যারন বার্ট্র্যান্ড

@ অ্যারোনবার্ট্র্যান্ড এটি প্রশ্ন থেকে 100% স্পষ্ট নয় যে পছন্দসই ফলাফলটি বর্তমান সুযোগ থেকে শেষ সন্নিবেশ (বিকল্পটি 1 সেই ক্ষেত্রে 2 এবং 3 এর চেয়ে পৃথক), তাই আমি বুঝতে পেরেছিলাম যে উভয় এবং কীভাবে তারা বর্ণনা করা ভাল ধারণা হবে পৃথক। তবে আমি তাতে একমত নই@@IDENTITY উত্পন্ন পরিচয় মূল্যবোধ পাওয়ার আদর্শ উপায় কখনই নয়। মূল কথাটি হ'ল MAX()বা TOP 1এর একটি কম নির্ভরযোগ্য সংস্করণের মতো IDENT_CURRENT(), যা আপনি যদি বুঝতে পারেন যে এটি কী করে তা ব্যবহার করার জন্য এটি পুরোপুরি সূক্ষ্ম ফাংশন। রক্ষণাবেক্ষণ কাজ বা কিছু জন্য দরকারী হতে পারে।
db2
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.