14

मैं एक बाधा जोड़ना चाहता हूं जो संबंधित तालिका से मूल्यों की जांच करेगी।CONSTRAINT दूरस्थ रूप से संबंधित तालिका (शामिल होने के माध्यम से) से मूल्यों की जांच करने के लिए

मैं 3 टेबल है:

CREATE TABLE somethink_usr_rel (
    user_id BIGINT NOT NULL, 
    stomethink_id BIGINT NOT NULL 
); 

CREATE TABLE usr (
    id BIGINT NOT NULL, 
    role_id BIGINT NOT NULL 
); 

CREATE TABLE role (
    id BIGINT NOT NULL, 
    type BIGINT NOT NULL 
); 

(तुम मुझे FK साथ बाधा डाल करने के लिए चाहते हैं, तो मुझे बताएं।)

मैं somethink_usr_rel कि role में type की जाँच करता है (करने के लिए एक बाधा जोड़ें "करना चाहते हैं दो तालिकाओं दूर "), उदाहरण के लिए:

ALTER TABLE somethink_usr_rel 
    ADD CONSTRAINT CH_sm_usr_type_check 
    CHECK (usr.role.type = 'SOME_ENUM'); 

मैं JOIN रों के साथ ऐसा करने की कोशिश की लेकिन कामयाब नहीं हुए। कोई विचार यह कैसे प्राप्त करें?

उत्तर

16

CHECK की कमी वर्तमान में अन्य तालिकाओं को संदर्भित नहीं कर सकते हैं:

इस उदाहरण पर एक नज़र डालें। Per documentation:

वर्तमान में, CHECK भाव सबक्वेरी शामिल है और न ही वर्तमान पंक्ति के कॉलम के अलावा अन्य चर का उल्लेख नहीं कर सकते हैं।

एक तरीका है demonstrated by @Wolph जैसे ट्रिगर का उपयोग करना।

एक स्वच्छ ट्रिगर्स (जो संदर्भित अखंडता को लागू करने के लिए अधिक मजबूत है) के बिना समाधान अनावश्यक कॉलम जोड़ना और उन्हें एफके बाधाओं में शामिल करना होगा। विस्तृत निर्देशों के साथ dba.SE पर इस करीबी उत्तर पर विचार करें:

एक अन्य विकल्प "नकली" अपरिवर्तनीय समारोह हो जांच कर रही है और प्रयोग है कि एक CHECK बाधा में होगा। पोस्टग्रेज़ इसकी अनुमति देंगे, लेकिन संभावित परिणामों से अवगत रहें। आप इसे NOT VALID बाधा बनाते हैं। विवरण:

7

CHECK बाधा एक विकल्प नहीं है यदि आपको जुड़ने की आवश्यकता है। आप एक ट्रिगर बना सकते हैं जो इसके बजाय एक त्रुटि उठाता है। http://www.postgresql.org/docs/9.1/static/plpgsql-trigger.html#PLPGSQL-TRIGGER-EXAMPLE

CREATE TABLE emp (
    empname text, 
    salary integer, 
    last_date timestamp, 
    last_user text 
); 

CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$ 
    BEGIN 
     -- Check that empname and salary are given 
     IF NEW.empname IS NULL THEN 
      RAISE EXCEPTION 'empname cannot be null'; 
     END IF; 
     IF NEW.salary IS NULL THEN 
      RAISE EXCEPTION '% cannot have null salary', NEW.empname; 
     END IF; 

     -- Who works for us when she must pay for it? 
     IF NEW.salary < 0 THEN 
      RAISE EXCEPTION '% cannot have a negative salary', NEW.empname; 
     END IF; 

     -- Remember who changed the payroll when 
     NEW.last_date := current_timestamp; 
     NEW.last_user := current_user; 
     RETURN NEW; 
    END; 
$emp_stamp$ LANGUAGE plpgsql; 

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp 
    FOR EACH ROW EXECUTE PROCEDURE emp_stamp(); 
0

... मैंने किया यह इतना (nazwa = उपयोगकर्ता नाम, firma = कंपनी का नाम):

CREATE TABLE users 
(
    id bigserial CONSTRAINT firstkey PRIMARY KEY, 
    nazwa character varying(20), 
    firma character varying(50) 
); 


CREATE TABLE test 
(
    id bigserial CONSTRAINT firstkey PRIMARY KEY, 
    firma character varying(50), 
    towar character varying(20), 
    nazwisko character varying(20) 
); 

ALTER TABLE public.test ENABLE ROW LEVEL SECURITY; 

CREATE OR REPLACE FUNCTION whoIAM3() RETURNS varchar(50) as $$ 
declare 
    result varchar(50); 
    BEGIN 
select into result users.firma from users where users.nazwa = current_user; 
    return result; 
    END; 

    $$ LANGUAGE plpgsql; 


CREATE POLICY user_policy ON public.test 
    USING (firma = whoIAM3()); 

CREATE FUNCTION test_trigger_function() 
RETURNS trigger AS $$ 
BEGIN 
    NEW.firma:=whoIam3(); 
return NEW; 
END 
$$ LANGUAGE 'plpgsql' 
CREATE TRIGGER test_trigger_insert BEFORE INSERT ON test FOR EACH ROW EXECUTE PROCEDURE test_trigger_function(); 
संबंधित मुद्दे