'ডিফল্ট' পতাকাটি কীভাবে কার্যকর করা যায় যা কেবলমাত্র একটি একক সারিতে সেট করা যায়


31

উদাহরণস্বরূপ, এটির মতো সারণী সহ:

create table foo(bar int identity, chk char(1) check (chk in('Y', 'N')));

পতাকাটি একটি char(1), একটি bitবা যা কিছু হিসাবে প্রয়োগ করা হয় তা বিবেচ্য নয়। আমি কেবল সীমাবদ্ধতা প্রয়োগ করতে সক্ষম হতে চাই যে এটি কেবল একটি একক সারিতে সেট করা যেতে পারে।


এই প্রশ্নটি দ্বারা অনুপ্রাণিত যা মাইএসকিউএল
জ্যাক ডগলাস

2
প্রশ্নটি যেভাবে শব্দযুক্ত তা বোঝায় যে একটি সারণী ব্যবহার করা অবশ্যই ভুল উত্তর হতে পারে। তবে কখনও কখনও (বেশিরভাগ বার?) অন্য টেবিল যুক্ত করা ভাল ধারণা। এবং একটি টেবিল যুক্ত করা সম্পূর্ণরূপে অজানাস্টিক ডাটাবেস।
মাইক শেরিল 'ক্যাট রিকল'

উত্তর:



16

এসকিউএল সার্ভার 2000, 2005:

আপনি একটি অনন্য সূচকে শুধুমাত্র একটি নাল অনুমোদিত তা এই সুবিধাটি নিতে পারেন:

create table t( id int identity, 
                chk1 char(1) not null default 'N' check(chk1 in('Y', 'N')), 
                chk2 as case chk1 when 'Y' then null else id end );
create unique index u_chk on t(chk2);

2000 এর জন্য আপনার প্রয়োজন হতে পারে SET ARITHABORT ON(এই তথ্যের জন্য @ জিবিএনকে ধন্যবাদ)


14

ওরাকল:

যেহেতু ওরাকল সমস্ত সূচিযুক্ত কলামগুলি নাল যেখানে প্রবেশের সূচি দেয় না তাই আপনি একটি ফাংশন ভিত্তিক অনন্য সূচক ব্যবহার করতে পারেন:

create table foo(bar integer, chk char(1) not null check (chk in('Y', 'N')));
create unique index idx on foo(case when chk='Y' then 'Y' end);

এই সূচকটি কেবলমাত্র সর্বাধিক কোনও একক সারিকে সূচক করবে।

এই সূচী তথ্যটি জেনে আপনি বিট কলামটি কিছুটা ভিন্নভাবে প্রয়োগ করতে পারেন:

create table foo(bar integer, chk char(1) check (chk ='Y') UNIQUE);

এখানে কলামের সম্ভাব্য মানগুলি chkহবে Yএবং NULL। সর্বাধিক কেবল একটি সারির মান থাকতে পারেY.


chk একটি not nullবাধা প্রয়োজন?
জ্যাক ডগলাস

@ জ্যাক: আপনি যদি শূন্যতা not nullনা চান তবে আপনি একটি সীমাবদ্ধতা যুক্ত করতে পারেন (প্রশ্নটির চশমা থেকে এটি আমার কাছে পরিষ্কার ছিল না)। শুধুমাত্র একটি সারিতে যে কোনও ক্ষেত্রে 'Y' মান থাকতে পারে।
ভিনসেন্ট মালগ্র্যাট

+1 আমি আপনাকে যা বলতে চাইছি তা দেখতে পেয়েছি - আপনি ঠিক বলেছেন এটি প্রয়োজনীয় নয় (তবে সম্ভবত কিছুটা নিচু, বিশেষত যদি এটির সাথে মিলিত হয় default)?
জ্যাক ডগলাস

2
@ জ্যাক: আপনার মন্তব্য আমাকে অনুধাবন করেছে যে কলামটিও হতে পারে Yবা nullআমার আপডেটটি যদি আপনি স্বীকার করেন তবে একটি আরও সহজ সম্ভাবনা উপলব্ধ ।
ভিনসেন্ট মালগ্র্যাট 15 ই

1
অপশন 2 এর অতিরিক্ত সুবিধা রয়েছে যে nullসূচিটি এড়িয়ে যাওয়ায় ক্ষুদ্রতর হবে - সম্ভবত কিছু স্পষ্টতার ব্যয়
জ্যাক ডগলাস

13

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

Person
-------
PersonID
Name
etc.
DefaultAddressID (fk to addressID)

Address
--------
AddressID
Street
City, State, Zip, etc.

আপনি ডিফল্ট অ্যাড্রেসইডকে nlalable করতে পারেন, তবে এইভাবে কাঠামো আপনার সীমাবদ্ধতা প্রয়োগ করে।


12

মাইএসকিউএল:

create table foo(bar serial, chk boolean unique);
insert into foo(chk) values(null);
insert into foo(chk) values(null);
insert into foo(chk) values(false);
insert into foo(chk) values(true);

select * from foo;
+-----+------+
| bar | chk  |
+-----+------+
|   1 | NULL |
|   2 | NULL |
|   3 |    0 |
|   4 |    1 |
+-----+------+

insert into foo(chk) values(true);
ERROR 1062 (23000): Duplicate entry '1' for key 2
insert into foo(chk) values(false);
ERROR 1062 (23000): Duplicate entry '0' for key 2

মাইএসকিউএলে চেক সীমাবদ্ধতাগুলি উপেক্ষা করা হয় যাতে আমাদের বিবেচনা করতে হবে nullবা falseভুয়া এবং trueসত্য হিসাবে। সর্বাধিক 1 সারি থাকতে পারেchk=true

আপনি চেক সীমাবদ্ধতার অভাবে কাজ হিসাবে সন্নিবেশ / আপডেটে falseরূপান্তর করতে ট্রিগার যুক্ত করার উন্নতি হিসাবে বিবেচনা করতে পারেন true- আইএমও এটি কোনও উন্নতি নয়।

আমি আশা করি যে এটি একটি চর (0) ব্যবহার করতে সক্ষম হবে কারণ এটি

আপনার যখন দুটি কলাম নিতে পারে এমন কলামের প্রয়োজন রয়েছে তখন এটিও বেশ সুন্দর: CHAR (0) NUL হিসাবে সংজ্ঞায়িত একটি কলাম কেবল একটি বিট দখল করে এবং কেবল NULL এবং '' মান গ্রহণ করতে পারে

দুর্ভাগ্যক্রমে, মাইআইএসএএম এবং ইনোডিবি কমপক্ষে, আমি পেয়েছি

ERROR 1167 (42000): The used storage engine can't index column 'chk'

--edit

এটি মাইএসকিউএল-এর পরে কোনও ভাল সমাধান নয়, এর booleanসমার্থক শব্দtinyint(1) এবং তাই 0 বা 1-এর চেয়ে নন-নাল মানকে অনুমতি দেয় এটি bitআরও ভাল পছন্দ হতে পারে


এটি আমার মন্তব্যটির উত্তর রোল্যান্ডোমাইএসকিউএলডিবিএর জবাব দিতে পারে: আমরা কি ডিআরআই দিয়ে মাইএসকিউএল সমাধান পেতে পারি?
gbn

এটা তোলে কারণ যদিও একটু কুৎসিত null, false, true- আমি আশ্চর্যবোধ করছ যদি কিছু neater হচ্ছে ...
জ্যাক ডগলাস

মাইএসকিউএলে খাঁটি ডিআরআই পদ্ধতির চেষ্টা করার জন্য @ জ্যাক - +1
রোল্যান্ডোমাইএসকিউএলডিবিএ

আমি এখানে মিথ্যা ব্যবহার এড়ানো পরামর্শ দিচ্ছি কারণ অনন্য প্রতিবন্ধকতা কেবল এই ধরণের একটি মিথ্যা মান সরবরাহ করতে পারে। যদি নালটি মিথ্যা প্রতিনিধিত্ব করে তবে এটি পুরোপুরি ধারাবাহিকভাবে ব্যবহার করা উচিত - অতিরিক্ত বৈধতা উপলব্ধ থাকলে মিথ্যা প্রতিরোধ কার্যকর করা যেতে পারে (যেমন জেএসআর -303 / হাইবারনেট-ভ্যালিডেটর)।
স্টিভ চেম্বারস

1
মাইএসকিউএল / মারিয়াডিবি এর সাম্প্রতিক সংস্করণগুলি ভার্চুয়াল কলামগুলি বাস্তবায়িত করে যা আমি বিশ্বাস করি যে dba.stackexchange.com/a/144847/94908
ম্যাটডাব্লুতে

10

SQL সার্ভার:

এটা কিভাবে করতে হবে:

  1. সবচেয়ে ভাল উপায় হ'ল একটি পরিশোধিত সূচক। ডিআরআই
    এসকিউএল সার্ভার 2008+ ব্যবহার করে

  2. স্বতন্ত্রতার সাথে গণিত কলাম। ডিআরআই ব্যবহার করে
    জ্যাক ডগলাসের উত্তর দেখুন। এসকিউএল সার্ভার 2005 এবং এর আগে

  3. একটি ইনডেক্স / উপাদানযুক্ত দৃশ্য যা ফিল্টার সূচকগুলির মতো।
    সমস্ত সংস্করণ ডিআরআই ব্যবহার করে ।

  4. ট্রিগার। কোড ব্যবহার করে, ডিআরআই নয়।
    সমস্ত সংস্করণ

কীভাবে এটি করবেন না:

  1. একটি ইউডিএফ দিয়ে সীমাবদ্ধতা পরীক্ষা করুন। এটি সম্মতি এবং স্ন্যাপশট বিচ্ছিন্নতার জন্য নিরাপদ নয়
    দেখুন ওয়ান দুই তিন চার

10

পোস্টগ্রি:

create table foo(bar serial, chk char(1) unique check(chk='Y'));
insert into foo default values;
insert into foo default values;
insert into foo(chk) values('Y');

select * from foo;
 bar | chk
-----+-----
   1 |
   2 |
   3 | Y

insert into foo(chk) values('Y');
ERROR:  duplicate key value violates unique constraint "foo_chk_key"

--edit

বা (আরও ভাল), একটি অনন্য আংশিক সূচক ব্যবহার করুন :

create table foo(bar serial, chk boolean not null default false);
create unique index foo_i on foo(chk) where chk;
insert into foo default values;
insert into foo default values;
insert into foo(chk) values(true);

select * from foo;
 bar | chk
-----+-----
   1 | f
   2 | f
   3 | t
(3 rows)

insert into foo(chk) values(true);
ERROR:  duplicate key value violates unique constraint "foo_i"

6

এই ধরণের সমস্যা হ'ল আমি আরও এই জিজ্ঞাসাবাদ জিজ্ঞাসা করার কারণ:

ডাটাবেসে অ্যাপ্লিকেশন সেটিংস

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


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

+1 তবে নোট করুন যে "একটি সম্পূর্ণ কলাম" আপনার আরডিবিএমএস এর উপর নির্ভর করে কোনও শারীরিক স্থান ব্যবহার করতে পারে না :)
জ্যাক ডগলাস

6

ব্যাপকভাবে প্রয়োগ করা প্রযুক্তি ব্যবহারের সম্ভাব্য পন্থা:

1) টেবিলে 'লেখক' সুবিধাগুলি প্রত্যাহার করুন। সিআরইউডি পদ্ধতি তৈরি করুন যা লেনদেনের সীমানায় সীমাবদ্ধতা কার্যকর করে তা নিশ্চিত করে।

2) 6NF: CHAR(1)কলামটি ড্রপ করুন । এর কার্ডিনালিটি একের বেশি হতে পারে না তা নিশ্চিত করার জন্য একটি রেফারেন্সিং সারণী সীমাবদ্ধ করুন:

alter table foo ADD UNIQUE (bar);

create table foo_Y
(
 x CHAR(1) DEFAULT 'x' NOT NULL UNIQUE CHECK (x = 'x'), 
 bar int references foo (bar)
);

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

3) CHAR(1)কলামটি ফেলে দিন। একটি seqপূর্ণসংখ্যা কলাম যুক্ত করুন। একটি অনন্য বাধা রাখুন seq। অ্যাপ্লিকেশন শব্দার্থকগুলি পরিবর্তন করুন যাতে বিবেচিত 'ডিফল্ট' হ'ল সারি যেখানে seqমান এক বা seqমান বৃহত্তম / ক্ষুদ্রতম মান বা অনুরূপ। সম্ভবত এই যুক্তি সজ্জিত করতে ভিউ ব্যবহার করুন।


5

যারা মাইএসকিউএল ব্যবহার করেন তাদের জন্য এখানে উপযুক্ত স্টোরড পদ্ধতি রয়েছে:

DELIMITER $$
DROP PROCEDURE IF EXISTS SetDefaultForZip;
CREATE PROCEDURE SetDefaultForZip (NEWID INT)
BEGIN
    DECLARE FOUND_TRUE,OLDID INT;

    SELECT COUNT(1) INTO FOUND_TRUE FROM PostalCode WHERE isDefault = TRUE;
    IF FOUND_TRUE = 1 THEN
        SELECT ID INTO OLDID FROM PostalCode WHERE isDefault = TRUE;
        IF NEWID <> OLDID THEN
            UPDATE PostalCode SET isDefault = FALSE WHERE ID = OLDID;
            UPDATE PostalCode SET isDefault = TRUE  WHERE ID = NEWID;
        END IF;
    ELSE
        UPDATE PostalCode SET isDefault = TRUE WHERE ID = NEWID;
    END IF;
END;
$$
DELIMITER ;

আপনার টেবিলটি পরিষ্কার আছে এবং সঞ্চিত পদ্ধতিটি কাজ করছে তা নিশ্চিত করার জন্য, আইডি 200 ডিফল্ট হিসাবে ধরে নিয়ে এই পদক্ষেপগুলি চালান:

ALTER TABLE PostalCode DROP INDEX isDefault_ndx;
UPDATE PostalCodes SET isDefault = FALSE;
ALTER TABLE PostalCode ADD INDEX isDefault_ndx (isDefault);
CALL SetDefaultForZip(200);
SELECT ID FROM PostalCodes WHERE isDefault = TRUE;

এখানে এমন একটি ট্রিগার রয়েছে যা সহায়তা করে:

DELIMITER $$
CREATE TRIGGER postalcodes_bu BEFORE UPDATE ON PostalCodes FOR EACH ROW
BEGIN
    DECLARE FOUND_TRUE,OLDID INT;
    IF NEW.isDefault = TRUE THEN
        SELECT COUNT(1) INTO FOUND_TRUE FROM PostalCode WHERE isDefault = TRUE;
        IF FOUND_TRUE = 1 THEN
            SELECT ID INTO OLDID FROM PostalCode WHERE isDefault = TRUE;
            UPDATE PostalCodes SET isDefault = FALSE WHERE ID = OLDID;
        END IF;
    END IF;
END;
$$
DELIMITER ;

আপনার টেবিলটি পরিষ্কার এবং ট্রিগার কাজ করছে তা নিশ্চিত করার জন্য, আইডি 200 ডিফল্ট হিসাবে ধরে নিয়ে এই পদক্ষেপগুলি চালান:

DROP TRIGGER postalcodes_bu;
ALTER TABLE PostalCode DROP INDEX isDefault_ndx;
UPDATE PostalCodes SET isDefault = FALSE;
ALTER TABLE PostalCode ADD INDEX isDefault_ndx (isDefault);
DELIMITER $$
CREATE TRIGGER postalcodes_bu BEFORE UPDATE ON PostalCodes FOR EACH ROW
BEGIN
    DECLARE FOUND_TRUE,OLDID INT;
    IF NEW.isDefault = TRUE THEN
        SELECT COUNT(1) INTO FOUND_TRUE FROM PostalCode WHERE isDefault = TRUE;
        IF FOUND_TRUE = 1 THEN
            SELECT ID INTO OLDID FROM PostalCode WHERE isDefault = TRUE;
            UPDATE PostalCodes SET isDefault = FALSE WHERE ID = OLDID;
        END IF;
    END IF;
END;
$$
DELIMITER ;
UPDATE PostalCodes SET isDefault = TRUE WHERE ID = 200;
SELECT ID FROM PostalCodes WHERE isDefault = TRUE;

একবার চেষ্টা করে দেখো !!!


3
মাইএসকিউএল-এর জন্য কোনও ডিআরআই ভিত্তিক সমাধান নেই? শুধু কোড? আমি কৌতূহলী কারণ আমি আরও বেশি করে মাইএসকিউএল ব্যবহার শুরু করেছি ...
gbn

4

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

আমার পোস্ট এখানে দেখুন


কোডের সংক্ষিপ্ত স্নিপেটের মতো আপনি এই উত্তরে আরও কিছুটা "মাংস" সরবরাহ করতে পারেন? এই মুহুর্তে এটি কেবলমাত্র কয়েকটি সাধারণ ধারণা এবং একটি লিঙ্ক।
নিক চ্যামাস

এখানে একটি উদাহরণ ফিট করা কিছুটা কঠিন হবে। আপনি যদি লিঙ্কটি ক্লিক করেন তবে আপনি যে "মাংস" সন্ধান করছেন তা পাবেন।
স্প্যাগেটিডবা

3

স্ট্যান্ডার্ড ট্রানজিশনাল এসকিউএল -২২, ব্যাপকভাবে প্রয়োগ করা হয়েছে যেমন এসকিউএল সার্ভার ২০০০ এবং এর বেশি:

টেবিল থেকে 'লেখক' সুবিধাগুলি প্রত্যাহার করুন। সহ WHERE chk = 'Y'এবং WHERE chk = 'N'যথাক্রমে দুটি মতামত তৈরি করুন WITH CHECK OPTION। জন্য WHERE chk = 'Y'দৃশ্য, প্রভাব যে তার cardinality এক অতিক্রম করতে পারে না একটি অনুসন্ধান শর্ত অন্তর্ভুক্ত। মতামত 'লেখক' সুযোগ সুবিধা প্রদান করুন।

দর্শনগুলির জন্য উদাহরণ কোড:

CREATE VIEW foo_chk_N
AS
SELECT *
  FROM foo AS f1
 WHERE chk = 'N' 
WITH CHECK OPTION

CREATE VIEW foo_chk_Y
AS
SELECT *
  FROM foo AS f1
 WHERE chk = 'Y' 
       AND 1 >= (
                 SELECT COUNT(*)
                   FROM foo AS f2
                  WHERE f2.chk = 'Y'
                )
WITH CHECK OPTION

এমনকি যদি আপনার আরডিবিএমএস এটি সমর্থন করে তবে এটি পাগলের মতো সিরিয়ালাইজ করবে তাই আপনার যদি একাধিক ব্যবহারকারী থাকে তবে আপনার সমস্যা হতে পারে
জ্যাক ডগলাস

যদি একাধিক ব্যবহারকারী একযোগে সংশোধন করে থাকেন তবে তাদের লাইনে দাঁড়াতে হবে (সিরিয়ালাইজ করা) - কখনও কখনও এটি ঠিক থাকে, প্রায়শই এটি হয় না (ভাবেন ভারী ওয়ালটিপি বা দীর্ঘ লেনদেন)।
জ্যাক ডগলাস

3
স্পষ্ট করার জন্য ধন্যবাদ। আমার অবশ্যই বলতে হবে যদি একাধিক ব্যবহারকারী ঘন ঘন একমাত্র ডিফল্ট সারি সেট করে থাকেন তবে নকশা পছন্দ (একই টেবিলের পতাকা কলাম) প্রশ্নবিদ্ধ।
onedaywhen

3

মাইএসকিউএল এবং মারিয়াডিবি-র জন্য কিছুটা মার্জিত ভার্চুয়াল কলামগুলি ব্যবহার করার জন্য এখানে একটি সমাধান রয়েছে। এর জন্য মাইএসকিউএল> = 5.7.6 বা মারিয়াডিবি> = 5.2 প্রয়োজন:

MariaDB [db]> create table foo(bar varchar(255), chk boolean);

MariaDB [db]> describe foo;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| bar   | varchar(255) | YES  |     | NULL    |       |
| chk   | tinyint(1)   | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

আপনি যদি অনন্য প্রতিবন্ধকতা প্রয়োগ করতে না চান তবে একটি ভার্চুয়াল কলাম তৈরি করুন: নুল:

MariaDB [db]> ALTER table foo ADD checked_bar varchar(255) as (IF(chk, bar, null)) PERSISTENT UNIQUE;

(মাইএসকিউএল এর STOREDপরিবর্তে ব্যবহার করুন PERSISTENT।)

MariaDB [db]> insert into foo(bar, chk) values('a', false);
Query OK, 1 row affected (0.00 sec)

MariaDB [db]> insert into foo(bar, chk) values('a', false);
Query OK, 1 row affected (0.01 sec)

MariaDB [salt_dev]> insert into foo(bar, chk) values('a', false);
Query OK, 1 row affected (0.00 sec)

MariaDB [db]> insert into foo(bar, chk) values('a', true);
Query OK, 1 row affected (0.00 sec)

MariaDB [db]> insert into foo(bar, chk) values('a', true);
ERROR 1062 (23000): Duplicate entry 'a' for key 'checked_bar'

MariaDB [db]> insert into foo(bar, chk) values('b', true);
Query OK, 1 row affected (0.00 sec)

MariaDB [db]> select * from foo;
+------+------+-------------+
| bar  | chk  | checked_bar |
+------+------+-------------+
| a    |    0 | NULL        |
| a    |    0 | NULL        |
| a    |    0 | NULL        |
| a    |    1 | a           |
| b    |    1 | b           |
+------+------+-------------+

1

স্ট্যান্ডার্ড পূর্ণ এসকিউএল 92: একটি একটি subquery ব্যবহার CHECKব্যাপকভাবে বাস্তবায়িত Access2000 সমর্থিত (ACE2007, জেট 4.0 যাই হোক না কেন) না উদাঃ যখন উপরে বাধ্যতা, ANSI-92 ক্যোয়ারী মোড

উদাহরণ কোড: CHECKঅ্যাক্সেসে নোটের সীমাবদ্ধতা সর্বদা সারণির স্তর। যেহেতু CREATE TABLEপ্রশ্নের বিবৃতিটি একটি সারি-স্তরের CHECKবাধা ব্যবহার করে, এটি কমা যোগ করে কিছুটা সংশোধন করা দরকার:

create table foo(bar int identity, chk char(1), check (chk in('Y', 'N')));

ALTER TABLE foo ADD 
   CHECK (1 >= (
                SELECT COUNT(*) 
                  FROM foo AS f2 
                 WHERE f2.chk = 'Y'
               ));

1
আমি যে কোনও আরডিবিএমএস ব্যবহার করেছি তাতে ভাল নয় ... প্রচুর পরিমাণে সতর্কতা রয়েছে
জ্যাক ডগলাস

0

আমি কেবল উত্তরগুলি দিয়ে স্কিম করেছিলাম, তাই আমি সম্ভবত একটি অনুরূপ উত্তরটি মিস করেছি। ধারনাটি হ'ল উত্পন্ন কলামটি হ'ল পিকে বা ধ্রুবক যা পিকে মান হিসাবে উপস্থিত থাকে না use

create table foo 
(  bar int not null primary key
,  chk char(1) check (chk in('Y', 'N'))
,  some_name generated always as ( case when chk = 'N' 
                                        then bar 
                                        else -1 
                                   end )
, unique (somename)
);

আফাইক এটি এসকিউএল ২০০৩-এ বৈধ ((যেহেতু আপনি যেখানে অগ্নিবিদ্যার সমাধান খুঁজছেন)। ডিবি 2 এটির অনুমতি দেয়, নিশ্চিত না যে আরও কতজন বিক্রেতা এটি গ্রহণ করে।

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