দুটি কলামের সংমিশ্রণে অনন্য সীমাবদ্ধতা যুক্ত করুন


149

আমার একটি টেবিল রয়েছে এবং কোনওভাবে একই ব্যক্তি আমার Personটেবিলে দু'বার প্রবেশ করেছেন। এই মুহুর্তে, প্রাথমিক কীটি কেবল একটি স্বায়ত্তশাসন তবে এখানে আরও দুটি ক্ষেত্র রয়েছে যা আমি অনন্য হতে বাধ্য করতে চাই।

উদাহরণস্বরূপ, ক্ষেত্রগুলি হ'ল:

ID  
Name  
Active  
PersonNumber  

আমি কেবল একটি অনন্য ব্যক্তি সংখ্যা এবং সক্রিয় = 1 দিয়ে 1 টি রেকর্ড চাই
(সুতরাং দুটি ক্ষেত্রের সংমিশ্রণটি অনন্য হওয়া দরকার)

এসকিউএল সার্ভারে বিদ্যমান টেবিলের সর্বোত্তম উপায় কী তা আমি এটি করতে পারি যদি অন্য কেউ যদি বিদ্যমান মানের হিসাবে একই মান সহ একটি সন্নিবেশ করে তবে এটি ব্যর্থ হয় তাই আমার অ্যাপ্লিকেশন কোডে আমাকে এ নিয়ে চিন্তা করতে হবে না।


3
আপনার অ্যাপ্লিকেশন কোডে আপনাকে এখনও এটি নিয়ে চিন্তিত হতে হবে।
ড্যান ব্রাকুক

2
ঠিক আছে, "এটি নিয়ে চিন্তা করতে হবে না" মানে কী? যদি কোনও ব্যবহারকারী একটি সদৃশ সন্নিবেশ করানোর চেষ্টা করে এবং এসকিউএল সার্ভার এটি না করে, আপনি কি তাদের বলতে চান না? অ্যাপ্লিকেশনটির মতো মনে হচ্ছে এটি সম্পর্কে চিন্তা করা দরকার।
অ্যারন বারট্র্যান্ড

উত্তর:


219

একবার আপনি নিজের নকল (গুলি) সরিয়ে ফেলেছেন:

ALTER TABLE dbo.yourtablename
  ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);

অথবা

CREATE UNIQUE INDEX uq_yourtablename
  ON dbo.yourtablename(column1, column2);

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

http://www.sqlperformance.com/2012/08/t-sql-queries/error-handling

http://www.mssqltips.com/sqlservertip/2632/checking-for-potential-constraint-violations-before-entering-sql-server-try-and-catch-logic/

আপনি যদি অ্যাপ্লিকেশনটিতে কোনও পরিবর্তন না করে অ্যাপ্লিকেশনটিতে বুবলি করা থেকে ব্যতিক্রমগুলি প্রতিরোধ করতে চান, আপনি INSTEAD OFট্রিগার ব্যবহার করতে পারেন :

CREATE TRIGGER dbo.BlockDuplicatesYourTable
 ON dbo.YourTable
 INSTEAD OF INSERT
AS
BEGIN
  SET NOCOUNT ON;

  IF NOT EXISTS (SELECT 1 FROM inserted AS i 
    INNER JOIN dbo.YourTable AS t
    ON i.column1 = t.column1
    AND i.column2 = t.column2
  )
  BEGIN
    INSERT dbo.YourTable(column1, column2, ...)
      SELECT column1, column2, ... FROM inserted;
  END
  ELSE
  BEGIN
    PRINT 'Did nothing.';
  END
END
GO

তবে আপনি যদি ব্যবহারকারীকে না জানান যে তারা sertোকানটি সম্পাদন করেনি, তারা কেন অবাক করে দেবে যে ডেটা সেখানে নেই এবং কোনও ব্যতিক্রমেরও খবর দেওয়া হয়নি।


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

USE tempdb;
GO

CREATE TABLE dbo.Person
(
  ID INT IDENTITY(1,1) PRIMARY KEY,
  Name NVARCHAR(32),
  Active BIT,
  PersonNumber INT
);
GO

ALTER TABLE dbo.Person 
  ADD CONSTRAINT uq_Person UNIQUE(PersonNumber, Active);
GO

-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
  VALUES(N'foo', 1, 22);
GO

-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
  VALUES(N'foo', 0, 22);
GO

-- fails:
INSERT dbo.Person(Name, Active, PersonNumber)
  VALUES(N'foo', 1, 22);
GO

এই সমস্তের পরে টেবিলের ডেটা:

ID   Name   Active PersonNumber
---- ------ ------ ------------
1    foo    1      22
2    foo    0      22

শেষ সন্নিবেশে ত্রুটি বার্তা:

এমএসজি 2627, স্তর 14, রাজ্য 1, লাইন 3 ইউনিক কী বাধা 'uq_Person' লঙ্ঘন। 'Dbo.Person' অবজেক্টে সদৃশ কী sertোকানো যায় না। বিবৃতিতে বাতিল করা হয়েছে।


3
@ লেওরা হ্যাঁ, আমি নিশ্চিত যে আমার উত্তর দুটি কলামে স্বতন্ত্রতার সাথে সম্পর্কিত ।
অ্যারন বারট্রান্ড

2
এটি নয় যে প্রতিটি কলামটি অনন্য হতে হবে, এর কলামগুলির সংমিশ্রণ (স্বাক্ষরকরণ) অনন্য হতে হবে। যে জানার জন্য . ।
লিওরা

14

এটি জিইউআইতেও করা যেতে পারে:

  1. "ব্যক্তি" টেবিলের নীচে সূচকগুলিতে ডান ক্লিক করুন
  2. ক্লিক / হাওর নতুন সূচক
  3. ক্লাস্টারবিহীন সূচক ক্লিক করুন ...

এখানে চিত্র বর্ণনা লিখুন

  1. একটি ডিফল্ট সূচকের নাম দেওয়া হবে তবে আপনি এটি পরিবর্তন করতে পারেন।
  2. অনন্য চেকবক্স চেক করুন
  3. অ্যাড ... বোতামটি ক্লিক করুন

এখানে চিত্র বর্ণনা লিখুন

  1. আপনি যে কলামগুলি অন্তর্ভুক্ত করতে চান তা পরীক্ষা করুন

এখানে চিত্র বর্ণনা লিখুন

  1. প্রতিটি উইন্ডোতে ঠিক আছে ক্লিক করুন ।

1
অনন্য বাধা এবং অনন্য সূচকের মধ্যে পার্থক্য কী? কারণ আপনি যখন ইউনিক সীমাবদ্ধতা সেট করেন, তখন এটির 900 বাইট সীমাবদ্ধতা থাকে তবে এটি ইউনিক সূচকের মতো মনে হয় না।
ব্যাটম্যাচি

2
কিছুই নিবন্ধটির জন্য নিবন্ধটি দেখুন: blog.sqlauthority.com/2007/04/26/…
এলি

আমার new Indexক্লিকযোগ্য নয় এটি অক্ষম রয়েছে :(
ফয়সাল

4
@ ফয়সাল সেই টেবিলটির জন্য আপনার খোলা ফলাফল / ডিজাইন উইন্ডোটি বন্ধ করুন এবং আবার চেষ্টা করুন।
কালানাগ


3

আমার ক্ষেত্রে, আমাকে অনেকগুলি নিষ্ক্রিয় এবং কেবল দুটি কীগুলির একটি মাত্র সংমিশ্রণের অনুমতি দেওয়া দরকার ছিল:

UUL_USR_IDF  UUL_UND_IDF    UUL_ATUAL
137          18             0
137          19             0
137          20             1
137          21             0

এটি কাজ করে বলে মনে হচ্ছে:

CREATE UNIQUE NONCLUSTERED INDEX UQ_USR_UND_UUL_USR_IDF_UUL_ATUAL
ON USER_UND(UUL_USR_IDF, UUL_ATUAL)
WHERE UUL_ATUAL = 1;

এখানে আমার পরীক্ষার মামলাগুলি রয়েছে:

SELECT * FROM USER_UND WHERE UUL_USR_IDF = 137

insert into USER_UND values (137, 22, 1) --I CAN NOT => Cannot insert duplicate key row in object 'dbo.USER_UND' with unique index 'UQ_USR_UND_UUL_USR_IDF_UUL_ATUAL'. The duplicate key value is (137, 1).
insert into USER_UND values (137, 23, 0) --I CAN
insert into USER_UND values (137, 24, 0) --I CAN

DELETE FROM USER_UND WHERE UUL_USR_ID = 137

insert into USER_UND values (137, 22, 1) --I CAN
insert into USER_UND values (137, 27, 1) --I CAN NOT => Cannot insert duplicate key row in object 'dbo.USER_UND' with unique index 'UQ_USR_UND_UUL_USR_IDF_UUL_ATUAL'. The duplicate key value is (137, 1).
insert into USER_UND values (137, 28, 0) --I CAN
insert into USER_UND values (137, 29, 0) --I CAN

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

0

এবং যদি আপনার কাছে প্রচুর প্রশ্ন সন্নিবেশ করা থাকে তবে প্রতিবার কোনও ইআরআরআর মেসেজ জাগাতে চান না, আপনি এটি করতে পারেন:

CREATE UNIQUE NONCLUSTERED INDEX SK01 ON dbo.Person(ID,Name,Active,PersonNumber) 
WITH(IGNORE_DUP_KEY = ON)

এখানে চিত্র বর্ণনা লিখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.