तालिका में अधिकतम पंक्तियों को केवल 1 तक कैसे सीमित करें


22

मेरे SQL सर्वर डेटाबेस में एक कॉन्फ़िगरेशन तालिका है और इस तालिका में केवल एक पंक्ति होनी चाहिए। भविष्य के डेवलपर्स को यह समझने में मदद करने के लिए कि मुझे एक से अधिक डेटा जोड़े जाने से रोकना है। मैंने इसके लिए ट्रिगर का उपयोग करने का विकल्प चुना है, नीचे ...

ALTER TRIGGER OnlyOneConfigRow
    ON [dbo].[Configuration]
    INSTEAD OF INSERT
AS
BEGIN
    DECLARE @HasZeroRows BIT;
    SELECT  @HasZeroRows = CASE
        WHEN COUNT (Id) = 0 THEN 1
        ELSE 0
    END
    FROM
        [dbo].[Configuration];

    IF EXISTS(SELECT [Id] FROM inserted) AND @HasZeroRows = 0
    BEGIN
        RAISERROR ('You should not add more than one row into the config table. ', 16, 1)    
    END
END

यह कोई त्रुटि नहीं देता है लेकिन पहली पंक्ति को अंदर जाने की अनुमति नहीं देता है।

इसके अलावा एक और अधिक प्रभावी / अधिक आत्म व्याख्या करने के तरीके को पंक्तियों की संख्या को सीमित किया जा सकता है जिसे तालिका में केवल 1 में डाला जा सकता है, इससे? मैं SQL सर्वर सुविधा में किसी भी बनाया याद आ रही है?


2
सिर्फ इस बात के स्पष्टीकरण के रूप में कि आपका मूल दृष्टिकोण क्यों काम नहीं कर रहा था: आप ट्रिगर के बजाय का उपयोग करते हैं, जिसका अर्थ है कि आपका कोड इन्सर्ट स्टेटमेंट के बजाय चलाया जाता है। इसलिए सम्मिलित होने के लिए, आपको इसे ट्रिगर के भाग के रूप में स्पष्ट रूप से शामिल करना होगा।
स्कॉट एम

जवाबों:


52

ये दो बाधाएँ करेंगी:

CREATE TABLE dbo.Configuration
( ConfigurationID TINYINT NOT NULL DEFAULT 1,
  -- the rest of the columns
  CONSTRAINT Configuration_PK 
    PRIMARY KEY (ConfigurationID),
  CONSTRAINT Configuration_OnlyOneRow 
    CHECK (ConfigurationID = 1)
) ;

आपको दोनों PRIMARY KEY(या एक UNIQUEबाधा) की आवश्यकता है, इसलिए किसी भी दो पंक्तियों का समान IDमूल्य नहीं है, और CHECKबाधा इसलिए सभी पंक्तियों का समान IDमूल्य (मनमाने ढंग से चुना गया 1) है।
संयोजन में, दो लगभग विपरीत बाधाएं पंक्तियों की संख्या को शून्य या एक तक सीमित करती हैं।


एक काल्पनिक DBMS पर (कोई वर्तमान SQL कार्यान्वयन इस निर्माण की अनुमति नहीं देता है) 0 कॉलम से मिलकर एक प्राथमिक कुंजी की अनुमति देता है, यह एक समाधान भी होगा:

CREATE TABLE dbo.Configuration
( -- no ConfigurationID needed at all
  -- the rest of the columns
  CONSTRAINT Configuration_PK 
    PRIMARY KEY ()                -- 0 columns!
) ;

24

आप आईडी को एक निरंतर मान का मूल्यांकन करने वाले एक गणना किए गए कॉलम के रूप में परिभाषित कर सकते हैं, और उस कॉलम को अद्वितीय घोषित कर सकते हैं:

CREATE TABLE dbo.Configuration
(
  ID AS CAST(1 AS tinyint),  -- or: AS bit
  ...  -- other columns
  CONSTRAINT UQ_Configuration_ID UNIQUE (ID)
);

9

तुम भी ट्रिगर का उपयोग कर सकते हैं ..

create trigger LimitTable
on YourTableToLimit
after insert
as
    declare @tableCount int
    select @tableCount = Count(*)
    from YourTableToLimit

    if @tableCount > 50
    begin
        rollback
    end
go

1

थोड़ी सी आवश्यकता लगती है, लेकिन हो-हम :) आप सिर्फ मेज पर एक बाधा डाल सकते हैं और फिर केवल तालिका में अपडेट (कोई सम्मिलित या हटाए नहीं) की अनुमति देते हैं?

CREATE TABLE dbo.Config (
    ID INT identity(1,1), 
    CONFIGURATION VARCHAR(MAX),
    constraint ck_limitrows CHECK (ID <=1) 
    );

यह हालांकि यह करने के लिए एक hackey तरीका का एक सा है, यह सिर्फ एक संग्रहीत कार्यविधि के माध्यम से कॉन्फ़िगरेशन में परिवर्तन लागू करने के लिए बेहतर नहीं होगा जो तब आपके लिए यह सभी तर्क संभाल सकता है?


2
बस सुनिश्चित करें कि कोई भी तालिका से हटा नहीं सकता है। यदि कोई हटाता है और फिर पुन: सम्मिलित करने का प्रयास करता है तो वह 2 की पहचान के साथ सम्मिलित करने का प्रयास करेगा जिसे वह अनुमति नहीं देगा।
Mat

5
यह IDएक 0या एक नकारात्मक मूल्य के लिए मना नहीं करता है । और @Mat अंक के रूप में, यह विफल हो जाएगा यदि आप पहली पंक्ति हटाए जाने पर दूसरी पंक्ति सम्मिलित करने का प्रयास करते हैं।
ypercube y

2
"विषम आवश्यकता" होने के कारण, मैं विन्यास सेटिंग्स के लिए एकल-पंक्ति तालिका का उपयोग करना पसंद करता हूं, बजाय प्रतीत होता है कि सामान्य ईएवी डिज़ाइन। पूर्व होने का लाभ यह है कि एक उपयुक्त डेटा प्रकार के साथ कॉलम बनाए जा सकते हैं और उपयुक्त बाधाओं को जोड़ा जा सकता है (अधिक आसानी से)।
केनी एविट

2
शायद मैं अपनी पिछली टिप्पणी में बहुत स्पष्ट नहीं था। का एक पक्ष प्रभाव "यह आईडी न करे नहीं है 0 के एक मूल्य या एक नकारात्मक एक है करने के लिए" है कि तालिका 2 या अधिक पंक्तियों के साथ समाप्त कर सकता है। पहचान संपत्ति अद्वितीय बाधा नहीं है।
ypercube y

3
यह बताने के लिए कि @ ypercube y ने क्या कहा है, इस समाधान के साथ आप उदाहरण INSERT INTO dbo.Config DEFAULT VALUES;के लिए एक बार कर सकते हैं , लेकिन आप इसे SET IDENTITY_INSERT dbo.Config ON; INSERT INTO dbo.Config (ID) VALUES (0); SET IDENTITY_INSERT dbo.Config OFF; कई बार अपना सकते हैं, और आप एक एकाधिक पंक्ति तालिका के साथ समाप्त करेंगे।
एंड्री एम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.