বিদ্যমান পিকে-তে স্ব-স্ব-সংযোজন যুক্ত করুন


14

আমি একটি ডিবিতে একটি টেবিল তৈরি করেছি যা ইতিমধ্যে অন্য ডিবিতে বিদ্যমান। এটি প্রাথমিকভাবে পুরানো ডিবি ডেটা দিয়ে জনবহুল হয়েছিল। টেবিলের পিকে সেই মানগুলি গ্রহণ করতে হয়েছিল যা ইতিমধ্যে সেই রেকর্ডগুলির মধ্যে রয়েছে, সুতরাং এটি স্বয়ংসোধ হতে পারে না।

এখন আমার নতুন টেবিলটির পিকেটিকে স্বতঃআধিকার হিসাবে থাকতে হবে। কিন্তু পিকে ইতিমধ্যে উপস্থিত থাকার পরে এবং ডেটা থাকার পরে আমি কীভাবে এটি করতে পারি?


3
আপনি যখন "স্বতঃআগ্রহ" বলছেন আপনি ঠিক কীটির উল্লেখ করছেন? এসকিউএল সার্ভারে কোনও কলামের জন্য এ জাতীয় কোনও সম্পত্তি নেই। মানে IDENTITY?
ম্যাক্স ভার্নন

হ্যাঁ, এমএসএসকিউএলে এটিকে বলা হয়। সাধারণভাবে ডাটাবেসে এটি একটি স্বয়ংসোধক পিকে।
হিকারি

উত্তর:


14

আমি আপনার প্রশ্নটি যেভাবে বুঝতে পারি তা হ'ল আপনার কাছে একটি কলাম সহ একটি বিদ্যমান টেবিল রয়েছে যা এখন অবধি ম্যানুয়াল মানগুলি দ্বারা জনবসতিপূর্ণ এবং এখন আপনি (1) এই কলামটি একটি IDENTITYকলাম তৈরি করতে চান এবং (2) নিশ্চিত হয়েছেন যে IDENTITYশুরুগুলি বিদ্যমান সারিগুলির মধ্যে অতি সাম্প্রতিক মান থেকে।

প্রথমে, কিছু টেস্ট ডেটা এতে খেলতে হবে:

CREATE TABLE dbo.ident_test (
    id    int NOT NULL,
    xyz   varchar(10) NOT NULL,
    CONSTRAINT PK_ident_test PRIMARY KEY CLUSTERED (id)
);

INSERT INTO dbo.ident_test (id, xyz)
VALUES (1, 'test'),
       (2, 'test'),
       (5, 'test'),
       (6, 'test'),
       (10, 'test'),
       (18, 'test'),
       (19, 'test'),
       (20, 'test');

লক্ষ্যটি হল সারণীর প্রাথমিক কী কলামটি করা id, একটি IDENTITYকলাম যা পরবর্তী রেকর্ডটি .োকানো হবে তার 21 এ শুরু হবে। এই উদাহরণস্বরূপ, কলামটি xyzটেবিলের অন্যান্য কলামগুলির সমস্ত উপস্থাপন করে।

আপনি কিছু করার আগে দয়া করে এই পোস্টের নীচে সতর্কতাগুলি পড়ুন।

প্রথমে, যদি কিছু ভুল হয়ে যায়:

BEGIN TRANSACTION;

এখন, আসুন একটি অস্থায়ী কাজের কলাম id_tempএবং যুক্ত কলামটি বিদ্যমান idকলামের মানগুলিতে সেট করুন:

ALTER TABLE dbo.ident_test ADD id_temp int NULL;
UPDATE dbo.ident_test SET id_temp=id;

এর পরে, আমাদের বিদ্যমান idকলামটি ফেলে দিতে হবে (আপনি IDENTITYএকটি বিদ্যমান কলামে কেবল "যুক্ত" করতে পারবেন না , আপনাকে কলামটি একটি হিসাবে তৈরি করতে হবে IDENTITY)। প্রাথমিক কীটিও যেতে হবে, কারণ কলামটি তার উপর নির্ভর করে।

ALTER TABLE dbo.ident_test DROP CONSTRAINT PK_ident_test;
ALTER TABLE dbo.ident_test DROP COLUMN id;

... এবং কলামটি আবার যুক্ত করুন, IDENTITYমূল কী সহ:

ALTER TABLE dbo.ident_test ADD id int IDENTITY(1, 1) NOT NULL;
ALTER TABLE dbo.ident_test ADD CONSTRAINT PK_ident_test PRIMARY KEY CLUSTERED (id);

আকর্ষণীয় হয়ে উঠেছে এখানে এখানে। আপনি IDENTITY_INSERTটেবিলটিতে সক্ষম করতে পারবেন , যার অর্থ আপনি IDENTITYযখন নতুন সারি সন্নিবেশ করছেন তখন আপনি কলামের মানগুলি ম্যানুয়ালি সংজ্ঞায়িত করতে পারেন (যদিও বিদ্যমান সারিগুলি আপডেট না করে)।

SET IDENTITY_INSERT dbo.ident_test ON;

এই সেটটি দিয়ে, DELETEসারণির সমস্ত সারি, তবে যে সারিগুলি আপনি মুছে ফেলছেন তা হ'ল OUTPUTএকই টেবিলে - তবে idকলামের জন্য নির্দিষ্ট মান সহ (ব্যাকআপ কলাম থেকে)।

DELETE FROM dbo.ident_test
OUTPUT deleted.id_temp AS id, deleted.xyz
INTO dbo.ident_test (id, xyz);

একবার হয়ে গেলে IDENTITY_INSERTআবার ফিরে যান।

SET IDENTITY_INSERT dbo.ident_test OFF;

আমরা যে অস্থায়ী কলামটি যুক্ত করেছি তা ফেলে দিন:

ALTER TABLE dbo.ident_test DROP COLUMN id_temp;

এবং অবশেষে, IDENTITYকলামটি idপুনরায় পুনরায় সাজানো হয়েছে , সুতরাং পরবর্তী রেকর্ডটি idকলামে সর্বাধিক বিদ্যমান সংখ্যার পরে আবার শুরু হবে :

DECLARE @maxid int;
SELECT @maxid=MAX(id) FROM dbo.ident_test;
DBCC CHECKIDENT ("dbo.ident_test", RESEED, @maxid)

উদাহরণ সারণীটি পরীক্ষা করা হচ্ছে, সর্বোচ্চ idসংখ্যা 20।

SELECT * FROM dbo.ident_test;

অন্য সারি যুক্ত করুন এবং এটির নতুন পরীক্ষা করুন IDENTITY:

INSERT INTO dbo.ident_test (xyz) VALUES ('New row');
SELECT * FROM dbo.ident_test;

উদাহরণস্বরূপ, নতুন সারিটি থাকবে id=21। অবশেষে, আপনি যদি খুশি হন তবে লেনদেন করুন:

COMMIT TRANSACTION;

গুরুত্বপূর্ণ

এটি একটি তুচ্ছ অপারেশন নয় এবং এটি বেশ কয়েকটি ঝুঁকি বহন করে যা সম্পর্কে আপনার সচেতন হওয়া উচিত।

  • নিবেদিত পরীক্ষার পরিবেশে এটি করুন। ব্যাকআপ আছে। :)

  • আমি BEGIN/COMMIT TRANSACTIONএটি ব্যবহার করতে পছন্দ করি কারণ এটি পরিবর্তন করার মাঝামাঝি সময়ে আপনি অন্য টেবিলের সাথে বিশৃঙ্খলা থেকে বাধা দেয় এবং এটি কিছু ভুল হয়ে গেলে সমস্ত কিছু ফিরিয়ে দেওয়ার সম্ভাবনা দেয়। তবে, আপনার লেনদেনের প্রতিশ্রুতি দেওয়ার আগে আপনার টেবিলে অ্যাক্সেস করার চেষ্টা করা অন্য যে কোনও প্রক্রিয়া অপেক্ষা করে শেষ হবে। আপনার কাছে একটি বড় টেবিল থাকে এবং / অথবা আপনি উত্পাদন পরিবেশে থাকলে এটি বেশ খারাপ হতে পারে।

  • OUTPUT .. INTOআপনার টার্গেট টেবিলটিতে বৈদেশিক কী বাধা বা এমন অনেকগুলি বৈশিষ্ট্য রয়েছে যা আমি আমার মাথার উপরের অংশটি মনে করতে পারি না work পরিবর্তে আপনি অস্থায়ী টেবিলের মধ্যে ডেটা অফ-লোড করতে পারেন এবং তারপরে এটি আবার মূল টেবিলের মধ্যে .োকাতে পারেন। আপনি পার্টিশন স্যুইচিং (আপনি পার্টিশন ব্যবহার না করেও) ব্যবহার করতে সক্ষম হতে পারেন।

  • এই বিবৃতিগুলি এক এক হিসাবে চালান, ব্যাচ হিসাবে বা সঞ্চিত পদ্ধতিতে নয়।

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

  • কোন অক্ষম INSERTএবং DELETEটেবিলের উপর ট্রিগার।

যদি টেবিলটি পুনরায় তৈরি করা একটি বিকল্প হয়:

যদি টেবিলটি পুনরায় তৈরি করা আপনার পক্ষে একটি বিকল্প হয় তবে সবকিছুই অনেক সহজ:

  • খালি টেবিলটি তৈরি করুন, idকলামটি একটি হিসাবে IDENTITY,
  • IDENTITY_INSERT ONটেবিলের জন্য সেট করুন ,
  • টেবিলটি বসান,
  • সেট করুন IDENTITY_INSERT OFF, এবং
  • পরিচয় নিয়ে গবেষণা করেছেন।

দুর্দান্ত উত্তর, অনেক অনেক ধন্যবাদ! প্রকৃতপক্ষে আমার ক্ষেত্রে আমি এটি সেট করতে IDENTITY_INSERT ON, পপুলেট করতে এবং অক্ষম করতে পারি। এটি আমি করতে চেয়েছিলাম, কিন্তু এমএসএসকিউএল এটি সমর্থন করে তা জানত না।
হিকারি

5

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

কোনও ডেটা মুভমেন্ট জড়িত নেই এবং তাই এটি সত্যিই দ্রুত সঞ্চালিত হয় (প্রায় তাত্ক্ষণিক)।

নমুনা টেবিল

প্রশ্নটি মূল টেবিলটি ডিডিএলটি দেখায় না। নিম্নলিখিত ডিডিএল এই উত্তরে উদাহরণ হিসাবে ব্যবহৃত হবে:

CREATE TABLE dbo.idT(
    id int not null
    , uid uniqueidentifier not null
    , name varchar(50)
);
ALTER TABLE dbo.idT ADD CONSTRAINT PK_idT PRIMARY KEY CLUSTERED(id);

0 থেকে 15 এর অর্ধ ডজন ডামি এলোমেলো আইডিস এই প্রশ্নের সাথে যুক্ত করা হয়েছে:

WITH ids(n) AS(
    SELECT x1.n+x2.n*4
    FROM (values(0), (3)) as x1(n)
    CROSS JOIN (values(0), (2), (3)) as x2(n)
)
INSERT INTO idt(id, uid, name)
SELECT n, NEWID(), NEWID() 
FROM ids

ইন ডেটা উদাহরণ IdT

id  uid                                     name
0   65533096-5007-43EA-88AD-D6776B3B94FA    6A69D4F2-D682-4168-A92F-4CD2E2DBC21D
3   CE87F1ED-BE1A-4F2D-8D62-E1ECA822D35B    AF0524D9-0DBB-41E1-883B-003CB4E4F012
8   34A1DBFD-4F92-4F34-9F04-4CDC824AB15A    02B4BDA4-D515-4262-9031-0BE496AC24CE
11  51606C95-9DE8-4C30-B23B-F915EEA41156    93258103-9C22-4F9C-85CF-712ED0FB3CE6
12  CEC80431-0513-4751-A250-0EB3390DACAB    2DA6B8AF-3EBC-42B3-A76C-028716E24661
15  5037EA83-286F-4EBC-AD7C-E237B570C1FF    095E51E9-8C38-4104-858F-D14AA810A550

সঙ্গে নতুন টেবিল IDENTITY(0, 1)

idTআইডিতে IDENTITY(0, 1)সম্পত্তিটির অভাব হ'ল একমাত্র সমস্যা । একই কাঠামোযুক্ত একটি নতুন টেবিল এবং IDENTITY(0, 1)তৈরি করা হয়েছে:

CREATE TABLE dbo.idT_Switch(
    id int identity(0, 1) not null
    , uid uniqueidentifier not null
    , name varchar(50)
);
ALTER TABLE dbo.idT_Switch ADD CONSTRAINT PK_idT_Switch PRIMARY KEY CLUSTERED(id);

বাদে IDENTITY(0, 1), idT_Switchঅভিন্ন idT

বিদেশী কী

idTএই কৌশলটি ব্যবহারের অনুমতি দেওয়ার জন্য বিদেশী কীগুলি অপসারণ করতে হবে।

পার্টিশন স্যুইচ

idTএবং idT_Switchটেবিল একটি সামঞ্জস্যপূর্ণ গঠন আছে। ব্যবহার করার পরিবর্তে DELETE, UPDATEএবং INSERTবিবৃতি থেকে সারি সরাতে idTকরতে idT_Switchবা idTনিজে ALTER TABLE ... SWITCHব্যবহার করা যেতে পারে:

ALTER TABLE dbo.idT
SWITCH TO dbo.idT_Switch;

PK_idT(পুরো টেবিল) এর একক 'পার্টিশন' সরানো হয়েছে PK_idT_Switch(এবং বিপরীতে)। idTএখন 0 টি সারি idT_Switchরয়েছে এবং এতে 6 টি সারি রয়েছে।

আপনি উত্স এবং গন্তব্য সামঞ্জস্যতা প্রয়োজনীয়তার সম্পূর্ণ তালিকা খুঁজে পেতে পারেন:

পার্টিশন স্যুইচিং ব্যবহার করে ডেটা দক্ষতার সাথে স্থানান্তর করা

নোট করুন যে এর ব্যবহারের জন্য SWITCHএন্টারপ্রাইজ সংস্করণ প্রয়োজন হয় না, কারণ এখানে কোনও স্পষ্ট পার্টিশন নেই। একটি বিভাজনযুক্ত টেবিলকে এসকিউএল সার্ভার ২০০৫ সাল থেকে একক পার্টিশন সহ একটি টেবিল হিসাবে বিবেচনা করা হয়।

প্রতিস্থাপন করা idT

idT এখন খালি এবং অকেজো এবং এটি ফেলে দেওয়া যেতে পারে:

DROP TABLE idT;

idT_Switchনাম পরিবর্তন করা যায় এবং পুরানো idTটেবিলটি প্রতিস্থাপন করা যায় :

EXECUTE sys.sp_rename
    @objname = N'dbo.idT_Switch',
    @newname = N'idT', -- note lack of schema prefix
    @objtype = 'OBJECT';

বিদেশী চাবি

নতুন idTটেবিলে আবার বিদেশী কী যুক্ত করা যায় । idTস্যুইচিংয়ের জন্য টেবিলগুলিকে সামঞ্জস্যপূর্ণ করতে অন্য যে কোনও কিছু থেকে পূর্বে সরানো হয়েছে সেগুলি আবারও করা দরকার।

Reseed

SELECT IDENT_CURRENT( 'dbo.idT');

এই কমান্ডটি 0 প্রদান করে। টেবিল আইডিটিতে ম্যাক্স (আইডি) = 15 সহ 6 টি সারি রয়েছে D ডিবিসিসি চেকিডেন্ট (টেবিলের নাম) ব্যবহার করা যেতে পারে:

DBCC CHECKIDENT ('dbo.idT');

১৫ টি 0 এর চেয়ে বড়, এটি ম্যাক্স (আইডি) অনুসন্ধান না করে স্বয়ংক্রিয়ভাবে পুনরায় পুনঃনির্ধারণ করা হবে:

যদি কোনও সারণীর জন্য বর্তমান পরিচয় মান পরিচয় কলামে সঞ্চিত সর্বাধিক পরিচয়ের মানের চেয়ে কম হয় তবে এটি পরিচয় কলামে সর্বাধিক মান ব্যবহার করে পুনরায় সেট করা হয়। এর পরে 'ব্যতিক্রম' বিভাগটি দেখুন।

IDENT_CURRENT এখন 15 ফেরত দেয় ।

পরীক্ষা করে ডেটা যুক্ত করুন

একটি সাধারণ INSERTবিবৃতি:

INSERT INTO idT(uid, name) SELECT NEWID(), NEWID();

এই সারি যুক্ত করে:

id  uid                                     name
16  B395D692-5D7B-4DFA-9971-A1497B8357A1    FF210D9E-4027-479C-B5D8-057E77FAF378

idকলাম এখন পরিচয় ব্যবহার করছে এবং নতুন ঢোকানো মান প্রকৃতপক্ষে 16 (15 + 1) হয়।

অধিক তথ্য

কৌশলটিতে আরও পটভূমি সহ এখানে সম্পর্কিত প্রশ্নোত্তর রয়েছে SWITCH:

কেন কলামে পরিচয় সম্পত্তি অপসারণ করা সমর্থিত নয়


4

আপনি যদি নতুন পরিচয় মান দিয়ে শুরু করতে চান তবে আপনার নিজের পরিচয়টি পুনরায় তৈরি করতে হবে। এর জন্য ডকুমেন্টেশনটি দেখুনCHECKIDENT

DBCC CHECKIDENT (yourtable, reseed, starting point)

0

সক্রিয় এবং অক্ষম পরিচয় নম্বর

যদি আপনার টেবিলটি ট্যাবলে_এ হয়

  1. পরিচয় কলাম সহ টেবিল TABLE_B TABLE_A এর অনুরূপ তৈরি করুন
  2. পরিচয়পত্রের নাম সেট করুন ট্যাবলেট_বি চালু করুন
  3. TABLE_A থেকে TABLE_B এ INSERT
  4. পরিচয়পত্রের নাম সেট করুন ট্যাবলেট_বি অফ
  5. টেবিল ট্যাবলেট ড্র করুন এবং টেবিলের নাম পরিবর্তন করুন এক্স এক্স sp_rename 'ট্যাবলেট_বি', 'টেবল_এ'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.