Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6893131
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T06:37:17+00:00 2026-05-27T06:37:17+00:00

I have two tables, SystemVariables and VariableOptions . SystemVariables should be self-explanatory, and VariableOptions

  • 0

I have two tables, SystemVariables and VariableOptions. SystemVariables should be self-explanatory, and VariableOptions contains all of the possible choices for all of the variables.

VariableOptions has a foreign key, variable_id, which states which variable it is an option for. SystemVariables has a foreign key, choice_id, which states which option is the currently selected one.

I’ve gotten around the circular relationship using use_alter on choice_id, and post_update on SystemVariables‘ choice relationship. However, I would like to add an extra database constraint that will ensure that choice_id is valid (i.e. it’s referring to an option that is referring back to it).

The logic I need, assuming that sysVar represents a row in the SystemVariables table, is basically:

VariableOptions[sysVar.choice_id].variable_id == sysVar.id

But I don’t know how to construct this kind of constraint using SQL, declarative, or any other method. If necessary I could just validate this at the application level, but I’d like to have it at the database level if possible. I’m using Postgres 9.1.

Is this possible?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T06:37:17+00:00Added an answer on May 27, 2026 at 6:37 am

    You can implement that without dirty tricks. Just extend the foreign key referencing the chosen option to include variable_id in addition to choice_id.

    Here is a working demo. Temporary tables, so you can easily play with it:

    CREATE TABLE systemvariables (
      variable_id int PRIMARY KEY
    , choice_id   int
    , variable    text
    );
       
    INSERT INTO systemvariables(variable_id, variable) VALUES
      (1, 'var1')
    , (2, 'var2')
    , (3, 'var3')
    ;
    
    CREATE TABLE variableoptions (
      option_id   int PRIMARY KEY
    , variable_id int REFERENCES systemvariables ON UPDATE CASCADE ON DELETE CASCADE
    , option      text
    , UNIQUE (option_id, variable_id)  -- needed for the FK
    );
    
    ALTER TABLE systemvariables
      ADD CONSTRAINT systemvariables_choice_id_fk
      FOREIGN KEY (choice_id, variable_id) REFERENCES variableoptions(option_id, variable_id);
    
    INSERT INTO variableoptions  VALUES
      (1, 'var1_op1', 1)
    , (2, 'var1_op2', 1)
    , (3, 'var1_op3', 1)
    , (4, 'var2_op1', 2)
    , (5, 'var2_op2', 2)
    , (6, 'var3_op1', 3)
    ;
    

    Choosing an associated option is allowed:

    UPDATE systemvariables SET choice_id = 2 WHERE variable_id = 1;
    UPDATE systemvariables SET choice_id = 5 WHERE variable_id = 2;
    UPDATE systemvariables SET choice_id = 6 WHERE variable_id = 3;
    

    But there is no getting out of line:

    UPDATE systemvariables SET choice_id = 7 WHERE variable_id = 3;
    UPDATE systemvariables SET choice_id = 4 WHERE variable_id = 1;
    
    ERROR:  insert or update on table "systemvariables" violates foreign key constraint "systemvariables_choice_id_fk"
    DETAIL: Key (choice_id,variable_id)=(4,1) is not present in table "variableoptions".
    

    Exactly what you wanted.

    All key columns NOT NULL

    I think I found a better solution in this later answer:

    • How to deal with mutually dependent inserts

    Addressing the @ypercube’s question in the comments, to avoid entries with unknown association make all key columns NOT NULL, including foreign keys.

    The circular dependency would normally make that impossible. It’s the classical chicken-egg problem: one of both has to be there first to spawn the other. But nature found a way around it, and so did Postgres: deferrable foreign key constraints.

    CREATE TABLE systemvariables (
      variable_id int PRIMARY KEY
    , variable    text
    , choice_id   int NOT NULL
    );
    
    CREATE TABLE variableoptions (
      option_id   int PRIMARY KEY
    , option      text
    , variable_id int NOT NULL REFERENCES systemvariables
         ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
    , UNIQUE (option_id, variable_id) -- needed for the foreign key
    );
    
    ALTER TABLE systemvariables
    ADD CONSTRAINT systemvariables_choice_id_fk FOREIGN KEY (choice_id, variable_id)
       REFERENCES variableoptions(option_id, variable_id) DEFERRABLE INITIALLY DEFERRED; -- no CASCADING here!
    

    New variables and associated options have to be inserted in the same transaction:

    BEGIN;
    
    INSERT INTO systemvariables (variable_id, variable, choice_id)
    VALUES
      (1, 'var1', 2)
    , (2, 'var2', 5)
    , (3, 'var3', 6);
    
    INSERT INTO variableoptions (option_id, option, variable_id)
    VALUES
      (1, 'var1_op1', 1)
    , (2, 'var1_op2', 1)
    , (3, 'var1_op3', 1)
    , (4, 'var2_op1', 2)
    , (5, 'var2_op2', 2)
    , (6, 'var3_op1', 3);
    
    END;
    

    The NOT NULL constraint cannot be deferred, it is enforced immediately. But the foreign key constraint can, because we defined it that way. It is checked at the end of the transaction, which avoids the chicken-egg problem.

    In this edited scenario, both foreign keys are deferred. You can enter variables and options in arbitrary sequence.
    You can even make it work with plain non-deferrable FK constraint if you enter related entries in both table in one statement using CTEs as detailed in the linked answer.

    You may have noticed that the first foreign key constraint has no CASCADE modifier. (It wouldn’t make sense to allow changes to variableoptions.variable_id to cascade back.

    On the other hand, the second foreign key has a CASCADE modifier and is defined DEFERRABLE nonetheless. This carries some limitations. The manual:

    Referential actions other than the NO ACTION check cannot be deferred,
    even if the constraint is declared deferrable.

    NO ACTION is the default.

    So, referential integrity checks on INSERT are deferred, but the declared cascading actions on DELETE and UPDATE are not. The following is not permitted in PostgreSQL 9.0 or later because constraints are enforced after each statement:

    UPDATE option SET var_id = 4 WHERE var_id = 5;
    DELETE FROM var WHERE var_id = 5;
    

    Details:

    • Constraint defined DEFERRABLE INITIALLY IMMEDIATE is still DEFERRED?
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have two tables: Transactions and TransactionAgents. TransactionAgents has a foreign key to Transactions
I have two tables that are joined together. A has many B Normally you
I have two tables, one that contains volunteers, and one that contains venues. Volunteers
I have two tables of concern here: users and race_weeks. User has many race_weeks,
I have two tables, one has about 1500 records and the other has about
I have two tables. One table contains information about Assets, another Table about their
I have two tables, I want to transfer all data from the first table
I have two tables Order , OrderStatus . Order has OrderId (pk), OrderStatusId (fk)
I have two tables with a foreign key constraint how can I delete rows
I have two tables. One contains Potential Customer information along with their Vehicle requirements

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.