শর্তাধীন অনন্য বাধা ra


95

আমার এমন একটি পরিস্থিতি রয়েছে যেখানে কলামগুলির সেটগুলিতে আমার একটি অনন্য বাধা প্রয়োগ করতে হবে, তবে কেবলমাত্র একটি কলামের মানের জন্য।

সুতরাং উদাহরণস্বরূপ আমার কাছে টেবিলের মতো একটি টেবিল রয়েছে (আইডি, নাম, রেকর্ডস্ট্যাটাস)।

রেকর্ডস্ট্যাটাসের কেবলমাত্র 1 বা 2 এর মূল্য থাকতে পারে (সক্রিয় বা মুছে ফেলা), এবং আমি তখনই (আইডি, রেকর্ডস্ট্যাটাস) অনন্য সীমাবদ্ধতা তৈরি করতে চাই, যখন রেকর্ডস্ট্যাটাস = 1 তখনই আমার কোনও যত্ন নেই কারণ একই সাথে একাধিক মুছে ফেলা রেকর্ড রয়েছে কিনা আইডি

ট্রিগার লেখার পাশাপাশি কি আমি এটি করতে পারি?

আমি এসকিউএল সার্ভার 2005 ব্যবহার করছি।


4
এই নকশাটি একটি সাধারণ ব্যথা। আপনি কি ডিজাইন পরিবর্তন করার বিষয়টি বিবেচনা করেছেন যাতে ধারণাটি থেকে 'মোছা' রেকর্ডগুলি শারীরিকভাবে টেবিল থেকে মুছে ফেলা হয় এবং সম্ভবত কোনও 'সংরক্ষণাগার' সারণিতে চলে যায়?
onedaywhen

4
... কারণ সাধারণ কী প্রয়োগের জন্য একটি অনন্য প্রতিবন্ধকতা লেখার অক্ষমতাটিকে একটি 'কোড গন্ধ', আইএমও হিসাবে বিবেচনা করা উচিত। যদি আপনি নকশাটি পরিবর্তন করতে না পারেন (এসকিউএল ডিডিএল) কারণ অন্য অনেক সারণী এই সারণিকে রেফারেন্স করে থাকে তবে আমি বাজি ধরব যে আপনার এসকিউএল ডিএমএল এর ফলেও ভোগাচ্ছে অর্থাৎ আপনাকে যোগ করার কথা মনে রাখতে হবে ... এবং টেবিল। রেকর্ডস্ট্যাটাস = 1 ' সর্বাধিক অনুসন্ধানের অবস্থার সাথে এবং এই টেবিলের সাথে জড়িত শর্তগুলিতে যোগদান করুন এবং সূক্ষ্ম বাগগুলির অভিজ্ঞতা যখন এটি অনিবার্যভাবে উপলক্ষে বাদ দেওয়া হয়।
onedaywhen

উত্তর:


37

এটির মতো চেক সীমাবদ্ধতা যুক্ত করুন। পার্থক্যটি হল, আপনি স্থিতি = 1 এবং গণনা> 0 হলে মিথ্যা ফিরিয়ে আনবেন।

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

CREATE TABLE CheckConstraint
(
  Id TINYINT,
  Name VARCHAR(50),
  RecordStatus TINYINT
)
GO

CREATE FUNCTION CheckActiveCount(
  @Id INT
) RETURNS INT AS BEGIN

  DECLARE @ret INT;
  SELECT @ret = COUNT(*) FROM CheckConstraint WHERE Id = @Id AND RecordStatus = 1;
  RETURN @ret;

END;
GO

ALTER TABLE CheckConstraint
  ADD CONSTRAINT CheckActiveCountConstraint CHECK (NOT (dbo.CheckActiveCount(Id) > 1 AND RecordStatus = 1));

INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 1);

INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 1);
INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 2);
-- Msg 547, Level 16, State 0, Line 14
-- The INSERT statement conflicted with the CHECK constraint "CheckActiveCountConstraint". The conflict occurred in database "TestSchema", table "dbo.CheckConstraint".
INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 1);

SELECT * FROM CheckConstraint;
-- Id   Name         RecordStatus
-- ---- ------------ ------------
-- 1    No Problems  2
-- 1    No Problems  2
-- 1    No Problems  2
-- 1    No Problems  1
-- 2    Oh no!       1
-- 2    Oh no!       2

ALTER TABLE CheckConstraint
  DROP CONSTRAINT CheckActiveCountConstraint;

DROP FUNCTION CheckActiveCount;
DROP TABLE CheckConstraint;

আমি টেবিল স্তরের চেক সীমাবদ্ধতার দিকে তাকালাম তবে ফাংশনে সন্নিবেশ করা বা আপডেট হওয়া মানগুলি পাস করার কোনও উপায় নেই, আপনি কীভাবে জানেন?
এনপি-হার্ড

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

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

এটি কেবলমাত্র আবেদিকভাবে সত্য। ডাটাবেস ধারাবাহিকভাবে এবং পূর্বাভাসের সাথে আচরণ করে। চেক সীমাবদ্ধতাটি সারণীতে সারি যুক্ত হওয়ার পরে এবং ডিবিএমএস দ্বারা লেনদেনের আগে সংঘটিত হবে এবং আপনি এটির উপর নির্ভর করতে পারবেন। সেই ব্লগটি একটি দুর্দান্ত অনন্য সমস্যার কথা বলছিল যেখানে আপনাকে একবারে কেবল একটি প্রবেশের পরিবর্তে সন্নিবেশের সেটগুলির বিরুদ্ধে বাধা কার্যকর করতে হবে। আশিশ একবারে একটি প্রবেশের জন্য সীমাবদ্ধতার জন্য জিজ্ঞাসা করছে এবং এই সীমাবদ্ধতা নির্ভুলভাবে, অনুমানযোগ্য এবং ধারাবাহিকভাবে কাজ করবে। আমি দুঃখিত যদি এই শব্দটি শোনা যায়; আমি চরিত্রের বাইরে চলে যাচ্ছিলাম।
ডি প্যাট্রিক

4
এটি সন্নিবেশকারীদের জন্য দুর্দান্ত কাজ করে তবে আপডেটগুলির জন্য কাজ করে না বলে মনে হয়। অন্যান্য সন্নিবেশগুলির পরে ইজি এটি যুক্ত করা যখন আমি আশা করি না। INCERT INTO INCO INTO CheckConstraint VALUES (1, 'কোনও সমস্যা নেই', 2); আপডেটের CheckConstraint সেট Recordstatus = 1 যেখানে নাম = 'কোন ProblemsA'
dwidel

152

দেখুন, ফিল্টারড সূচক । ডকুমেন্টেশন (জোর আমার) থেকে:

একটি ফিল্টারড সূচকটি একটি অনুকূলিত ননক্লাস্টারড সূচক যা বিশেষভাবে ডেটাগুলির একটি সংজ্ঞায়িত উপসেট থেকে নির্বাচন করে এমন ক্যোয়ারীগুলি কভার করার জন্য উপযুক্ত। এটি টেবিলের সারিগুলির একটি অংশকে সূচক করতে একটি ফিল্টার প্রিকেট ব্যবহার করে। একটি সুনির্দিষ্ট ডিজাইন করা ফিল্টারড ইনডেক্স পূর্ণ-টেবিল সূচকের তুলনায় সূচি রক্ষণাবেক্ষণ এবং স্টোরেজ ব্যয় হ্রাস করার পাশাপাশি ক্যোয়ারি পারফরম্যান্সকে উন্নত করতে পারে।

এবং এখানে একটি ফিল্টার প্রিনিকেটের সাথে একটি অনন্য সূচক সংযুক্ত করার একটি উদাহরণ রয়েছে:

create unique index MyIndex
on MyTable(ID)
where RecordStatus = 1;

এই মূলত স্বতন্ত্রতা enforces IDযখন RecordStatusহয় 1

সেই সূচকটি তৈরি হওয়ার পরে, একটি স্বতন্ত্রতা লঙ্ঘন একটি ত্রাস বাড়াবে:

এমএসজি 2601, স্তর 14, রাজ্য 1, লাইন 13
অনন্য সূচক 'মাই ইন্ডেক্স' সহ 'ডিবিও.মাইটিবেবল' অবজেক্টে সদৃশ কী সারিটি প্রবেশ করতে পারে না। সদৃশ কী এর মান (9999)।

দ্রষ্টব্য: ফিল্টারড সূচকটি এসকিউএল সার্ভার ২০০৮ সালে প্রবর্তিত হয়েছিল। এসকিউএল সার্ভারের পূর্ববর্তী সংস্করণগুলির জন্য, দয়া করে এই উত্তরটি দেখুন


নোট করুন যে এসকিউএল সার্ভারের ansi_paddingফিল্টারড সূচীগুলির জন্য প্রয়োজন , তাই নিশ্চিত করুন যে SET ANSI_PADDING ONফিল্টারড সূচক তৈরির আগে নির্বাহের মাধ্যমে এই বিকল্পটি চালু হয়েছে ।
নেক্সা

10

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


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

3

আপনি এটি সত্যই হ্যাকি উপায়ে করতে পারেন ...

আপনার টেবিলে একটি স্কিমাবাউন্ড ভিউ তৈরি করুন।

সারণী যেখানেই রেকর্ড স্ট্যাটাস = 1 থেকে যা যা দেখুন দেখুন তৈরি করুন

এখন আপনি যে ক্ষেত্রগুলি চান সেগুলি দিয়ে ভিউতে একটি অনন্য বাধা তৈরি করুন।

স্কিমাবাউন্ড ভিউ সম্পর্কে একটি নোট যদিও, আপনি যদি অন্তর্নিহিত সারণীগুলি পরিবর্তন করেন তবে আপনাকে দৃশ্যটি পুনরায় তৈরি করতে হবে। এর জন্য প্রচুর গটচাছ।


এটি একটি দুর্দান্ত পরামর্শ, এবং এটি "হ্যাকি" নয়। এই ফিল্টারড সূচক বিকল্প সম্পর্কে আরও তথ্য এখানে ।
স্কট হুইটলক

এটি একটি খারাপ ধারণা। প্রশ্ন এটা নয়।
ফ্যাবিয়ানোথর

আমি একবার স্কিমাবাউন্ড ভিউ ব্যবহার করেছি, এবং ভুলটির পুনরাবৃত্তি করি নি। তারা কাজ করতে একটি রাজকীয় ব্যথা হতে পারে। আপনি যদি অন্তর্নিহিত টেবিলটি পরিবর্তন করেন তবে আপনাকে দৃশ্যটি পুনরায় তৈরি করতে হবে না - আপনাকে কমপক্ষে এসকিউএল সার্ভারে সমস্ত দর্শনগুলির জন্য এটি করতে হবে do এটি হ'ল আপনি প্রথম দৃশ্যটি বাদ না দিয়ে টেবিলটি পরিবর্তন করতে পারবেন না, যা আপনি প্রথমে উল্লেখগুলি বাদ দিয়ে নাও করতে পারবেন। ওহ, প্লাস স্টোরেজ সমস্যাযুক্ত হতে পারে - হয় জায়গার কারণে, বা ব্যয়ের কারণে এটি সন্নিবেশ করানো এবং আপডেট করা যায়।
ম্যাটডব্লিউ

1

কারণ, আপনি সদৃশকে অনুমতি দিতে যাচ্ছেন, একটি অনন্য বাধা কাজ করবে না। আপনি রেকর্ডস্ট্যাটাস কলামের জন্য একটি চেক সীমাবদ্ধতা এবং INSERT এর জন্য একটি সঞ্চিত পদ্ধতি তৈরি করতে পারেন যা সদৃশ আইডি সন্নিবেশ করার আগে বিদ্যমান সক্রিয় রেকর্ডগুলি পরীক্ষা করে।


1

আপনি যদি বিলের পরামর্শ অনুসারে রেকর্ডস্ট্যাটাস হিসাবে NULL ব্যবহার করতে না পারেন তবে আপনি তার ধারণাটি একটি ফাংশন-ভিত্তিক সূচকের সাথে একত্রিত করতে পারেন। এমন একটি ফাংশন তৈরি করুন যা NUL ফেরত দেয় যদি রেকর্ডস্ট্যাটাস আপনার সীমাবদ্ধতায় (এবং অন্যথায় রেকর্ডস্ট্যাটাস) বিবেচনা করতে চান সেই মানগুলির মধ্যে না হয় এবং তার উপর একটি সূচক তৈরি করে।

এতে আপনার সুবিধা হবে যে আপনার সীমাবদ্ধতার মধ্যে সারণীতে অন্য সারিগুলি আপনাকে স্পষ্টভাবে পরীক্ষা করতে হবে না, যা আপনাকে পারফরম্যান্সের সমস্যার কারণ হতে পারে।

আমার বলা উচিত যে আমি এসকিউএল সার্ভারটি মোটেই জানি না, তবে আমি ওরাকলে এই পদ্ধতির সফলভাবে ব্যবহার করেছি।


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