How to Add Check Constraint between Tables (or change DDL)?












1















Given the following PostgreSQL table definitions:



postgres=# create table if not exists messages(
postgres(# id serial primary key,
postgres(# max_length smallint not null check (max_length > 0),
postgres(# default_text text check (length(default_text) <= max_length),
postgres(# created_on timestamp with time zone not null
postgres(# );
CREATE TABLE
postgres=#
postgres=# create table if not exists customized_messages(
postgres(# message_id serial references messages(id) not null,
postgres(# message text not null,
postgres(# created_on timestamp with time zone not null
postgres(# );
CREATE TABLE


how can I enforce length(customized_messages.text) is <= messages.max_length per the foreign key constraint?



Note that, as-is, I can do the following:



postgres=# insert into messages (id, max_length, default_text, created_on) values (1, 5, null, current_timestamp);
INSERT 0 1
postgres=# insert into customized_messages (message_id, message, created_on) values (1, 'longer than 5', current_timestamp);
INSERT 0 1
postgres=# select * from messages;
id | max_length | default_text | created_on
----+------------+--------------+-------------------------------
1 | 5 | | 2019-01-18 14:12:59.692075-05
(1 row)
postgres=# select * from customized_messages;
message_id | message | created_on
------------+---------------+-------------------------------
1 | longer than 5 | 2019-01-18 14:13:38.226987-05
(1 row)


So, I would like to not allow, e.g. check constraint or something else, the longer than 5 to be inserted since its length is > 5.










share|improve this question

























  • Check constraint cannot reference another table. stackoverflow.com/a/27107470/3270427

    – McNets
    12 hours ago











  • Would table inheritance be a good idea, i.e. allow me to enforce this constraint?

    – Kevin Meredith
    12 hours ago











  • imho your best option is a trigger or a function.

    – McNets
    12 hours ago


















1















Given the following PostgreSQL table definitions:



postgres=# create table if not exists messages(
postgres(# id serial primary key,
postgres(# max_length smallint not null check (max_length > 0),
postgres(# default_text text check (length(default_text) <= max_length),
postgres(# created_on timestamp with time zone not null
postgres(# );
CREATE TABLE
postgres=#
postgres=# create table if not exists customized_messages(
postgres(# message_id serial references messages(id) not null,
postgres(# message text not null,
postgres(# created_on timestamp with time zone not null
postgres(# );
CREATE TABLE


how can I enforce length(customized_messages.text) is <= messages.max_length per the foreign key constraint?



Note that, as-is, I can do the following:



postgres=# insert into messages (id, max_length, default_text, created_on) values (1, 5, null, current_timestamp);
INSERT 0 1
postgres=# insert into customized_messages (message_id, message, created_on) values (1, 'longer than 5', current_timestamp);
INSERT 0 1
postgres=# select * from messages;
id | max_length | default_text | created_on
----+------------+--------------+-------------------------------
1 | 5 | | 2019-01-18 14:12:59.692075-05
(1 row)
postgres=# select * from customized_messages;
message_id | message | created_on
------------+---------------+-------------------------------
1 | longer than 5 | 2019-01-18 14:13:38.226987-05
(1 row)


So, I would like to not allow, e.g. check constraint or something else, the longer than 5 to be inserted since its length is > 5.










share|improve this question

























  • Check constraint cannot reference another table. stackoverflow.com/a/27107470/3270427

    – McNets
    12 hours ago











  • Would table inheritance be a good idea, i.e. allow me to enforce this constraint?

    – Kevin Meredith
    12 hours ago











  • imho your best option is a trigger or a function.

    – McNets
    12 hours ago
















1












1








1








Given the following PostgreSQL table definitions:



postgres=# create table if not exists messages(
postgres(# id serial primary key,
postgres(# max_length smallint not null check (max_length > 0),
postgres(# default_text text check (length(default_text) <= max_length),
postgres(# created_on timestamp with time zone not null
postgres(# );
CREATE TABLE
postgres=#
postgres=# create table if not exists customized_messages(
postgres(# message_id serial references messages(id) not null,
postgres(# message text not null,
postgres(# created_on timestamp with time zone not null
postgres(# );
CREATE TABLE


how can I enforce length(customized_messages.text) is <= messages.max_length per the foreign key constraint?



Note that, as-is, I can do the following:



postgres=# insert into messages (id, max_length, default_text, created_on) values (1, 5, null, current_timestamp);
INSERT 0 1
postgres=# insert into customized_messages (message_id, message, created_on) values (1, 'longer than 5', current_timestamp);
INSERT 0 1
postgres=# select * from messages;
id | max_length | default_text | created_on
----+------------+--------------+-------------------------------
1 | 5 | | 2019-01-18 14:12:59.692075-05
(1 row)
postgres=# select * from customized_messages;
message_id | message | created_on
------------+---------------+-------------------------------
1 | longer than 5 | 2019-01-18 14:13:38.226987-05
(1 row)


So, I would like to not allow, e.g. check constraint or something else, the longer than 5 to be inserted since its length is > 5.










share|improve this question
















Given the following PostgreSQL table definitions:



postgres=# create table if not exists messages(
postgres(# id serial primary key,
postgres(# max_length smallint not null check (max_length > 0),
postgres(# default_text text check (length(default_text) <= max_length),
postgres(# created_on timestamp with time zone not null
postgres(# );
CREATE TABLE
postgres=#
postgres=# create table if not exists customized_messages(
postgres(# message_id serial references messages(id) not null,
postgres(# message text not null,
postgres(# created_on timestamp with time zone not null
postgres(# );
CREATE TABLE


how can I enforce length(customized_messages.text) is <= messages.max_length per the foreign key constraint?



Note that, as-is, I can do the following:



postgres=# insert into messages (id, max_length, default_text, created_on) values (1, 5, null, current_timestamp);
INSERT 0 1
postgres=# insert into customized_messages (message_id, message, created_on) values (1, 'longer than 5', current_timestamp);
INSERT 0 1
postgres=# select * from messages;
id | max_length | default_text | created_on
----+------------+--------------+-------------------------------
1 | 5 | | 2019-01-18 14:12:59.692075-05
(1 row)
postgres=# select * from customized_messages;
message_id | message | created_on
------------+---------------+-------------------------------
1 | longer than 5 | 2019-01-18 14:13:38.226987-05
(1 row)


So, I would like to not allow, e.g. check constraint or something else, the longer than 5 to be inserted since its length is > 5.







postgresql check-constraints






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 12 hours ago







Kevin Meredith

















asked 12 hours ago









Kevin MeredithKevin Meredith

1548




1548













  • Check constraint cannot reference another table. stackoverflow.com/a/27107470/3270427

    – McNets
    12 hours ago











  • Would table inheritance be a good idea, i.e. allow me to enforce this constraint?

    – Kevin Meredith
    12 hours ago











  • imho your best option is a trigger or a function.

    – McNets
    12 hours ago





















  • Check constraint cannot reference another table. stackoverflow.com/a/27107470/3270427

    – McNets
    12 hours ago











  • Would table inheritance be a good idea, i.e. allow me to enforce this constraint?

    – Kevin Meredith
    12 hours ago











  • imho your best option is a trigger or a function.

    – McNets
    12 hours ago



















Check constraint cannot reference another table. stackoverflow.com/a/27107470/3270427

– McNets
12 hours ago





Check constraint cannot reference another table. stackoverflow.com/a/27107470/3270427

– McNets
12 hours ago













Would table inheritance be a good idea, i.e. allow me to enforce this constraint?

– Kevin Meredith
12 hours ago





Would table inheritance be a good idea, i.e. allow me to enforce this constraint?

– Kevin Meredith
12 hours ago













imho your best option is a trigger or a function.

– McNets
12 hours ago







imho your best option is a trigger or a function.

– McNets
12 hours ago












1 Answer
1






active

oldest

votes


















2














One way is to duplicate the max_length column and enforce that they have identical values in the two tables with a composite foreign key (instead of the simple one):



create table if not exists messages(
id serial
primary key,
max_length smallint not null
check (max_length > 0),
default_text text
check (length(default_text) <= max_length),
created_on timestamp with time zone not null,
unique (id, max_length)
);


create table if not exists customized_messages(
message_id int not null,
max_length smallint not null,
message text not null
check (length(message_text) <= max_length),
created_on timestamp with time zone not null,
foreign key (id, max_length)
references messages (id, max_length)
);




Note (irrelevant to the question): the message_id column in the 2nd table does not make sense to be serial and at the same time foreign key to the 1st table.






share|improve this answer


























  • Do you like your proposal more than adding a trigger?

    – Kevin Meredith
    11 hours ago











  • @KevinMeredith yeah, DDL >> triggers in my love list ;)

    – ypercubeᵀᴹ
    11 hours ago











  • So I don't need to add the check (max_length > 0) in customized_messages since it's already done in messages?

    – Kevin Meredith
    11 hours ago











  • Yes, the foreign key and the check constraint in messages guarantees that.

    – ypercubeᵀᴹ
    11 hours ago








  • 1





    Thanks! I'll accept in ~1 hour unless I see another answer (just to give time to other posters). Why is unique (id, max_length) needed though?

    – Kevin Meredith
    11 hours ago











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f227512%2fhow-to-add-check-constraint-between-tables-or-change-ddl%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














One way is to duplicate the max_length column and enforce that they have identical values in the two tables with a composite foreign key (instead of the simple one):



create table if not exists messages(
id serial
primary key,
max_length smallint not null
check (max_length > 0),
default_text text
check (length(default_text) <= max_length),
created_on timestamp with time zone not null,
unique (id, max_length)
);


create table if not exists customized_messages(
message_id int not null,
max_length smallint not null,
message text not null
check (length(message_text) <= max_length),
created_on timestamp with time zone not null,
foreign key (id, max_length)
references messages (id, max_length)
);




Note (irrelevant to the question): the message_id column in the 2nd table does not make sense to be serial and at the same time foreign key to the 1st table.






share|improve this answer


























  • Do you like your proposal more than adding a trigger?

    – Kevin Meredith
    11 hours ago











  • @KevinMeredith yeah, DDL >> triggers in my love list ;)

    – ypercubeᵀᴹ
    11 hours ago











  • So I don't need to add the check (max_length > 0) in customized_messages since it's already done in messages?

    – Kevin Meredith
    11 hours ago











  • Yes, the foreign key and the check constraint in messages guarantees that.

    – ypercubeᵀᴹ
    11 hours ago








  • 1





    Thanks! I'll accept in ~1 hour unless I see another answer (just to give time to other posters). Why is unique (id, max_length) needed though?

    – Kevin Meredith
    11 hours ago
















2














One way is to duplicate the max_length column and enforce that they have identical values in the two tables with a composite foreign key (instead of the simple one):



create table if not exists messages(
id serial
primary key,
max_length smallint not null
check (max_length > 0),
default_text text
check (length(default_text) <= max_length),
created_on timestamp with time zone not null,
unique (id, max_length)
);


create table if not exists customized_messages(
message_id int not null,
max_length smallint not null,
message text not null
check (length(message_text) <= max_length),
created_on timestamp with time zone not null,
foreign key (id, max_length)
references messages (id, max_length)
);




Note (irrelevant to the question): the message_id column in the 2nd table does not make sense to be serial and at the same time foreign key to the 1st table.






share|improve this answer


























  • Do you like your proposal more than adding a trigger?

    – Kevin Meredith
    11 hours ago











  • @KevinMeredith yeah, DDL >> triggers in my love list ;)

    – ypercubeᵀᴹ
    11 hours ago











  • So I don't need to add the check (max_length > 0) in customized_messages since it's already done in messages?

    – Kevin Meredith
    11 hours ago











  • Yes, the foreign key and the check constraint in messages guarantees that.

    – ypercubeᵀᴹ
    11 hours ago








  • 1





    Thanks! I'll accept in ~1 hour unless I see another answer (just to give time to other posters). Why is unique (id, max_length) needed though?

    – Kevin Meredith
    11 hours ago














2












2








2







One way is to duplicate the max_length column and enforce that they have identical values in the two tables with a composite foreign key (instead of the simple one):



create table if not exists messages(
id serial
primary key,
max_length smallint not null
check (max_length > 0),
default_text text
check (length(default_text) <= max_length),
created_on timestamp with time zone not null,
unique (id, max_length)
);


create table if not exists customized_messages(
message_id int not null,
max_length smallint not null,
message text not null
check (length(message_text) <= max_length),
created_on timestamp with time zone not null,
foreign key (id, max_length)
references messages (id, max_length)
);




Note (irrelevant to the question): the message_id column in the 2nd table does not make sense to be serial and at the same time foreign key to the 1st table.






share|improve this answer















One way is to duplicate the max_length column and enforce that they have identical values in the two tables with a composite foreign key (instead of the simple one):



create table if not exists messages(
id serial
primary key,
max_length smallint not null
check (max_length > 0),
default_text text
check (length(default_text) <= max_length),
created_on timestamp with time zone not null,
unique (id, max_length)
);


create table if not exists customized_messages(
message_id int not null,
max_length smallint not null,
message text not null
check (length(message_text) <= max_length),
created_on timestamp with time zone not null,
foreign key (id, max_length)
references messages (id, max_length)
);




Note (irrelevant to the question): the message_id column in the 2nd table does not make sense to be serial and at the same time foreign key to the 1st table.







share|improve this answer














share|improve this answer



share|improve this answer








edited 11 hours ago

























answered 11 hours ago









ypercubeᵀᴹypercubeᵀᴹ

74.9k11127208




74.9k11127208













  • Do you like your proposal more than adding a trigger?

    – Kevin Meredith
    11 hours ago











  • @KevinMeredith yeah, DDL >> triggers in my love list ;)

    – ypercubeᵀᴹ
    11 hours ago











  • So I don't need to add the check (max_length > 0) in customized_messages since it's already done in messages?

    – Kevin Meredith
    11 hours ago











  • Yes, the foreign key and the check constraint in messages guarantees that.

    – ypercubeᵀᴹ
    11 hours ago








  • 1





    Thanks! I'll accept in ~1 hour unless I see another answer (just to give time to other posters). Why is unique (id, max_length) needed though?

    – Kevin Meredith
    11 hours ago



















  • Do you like your proposal more than adding a trigger?

    – Kevin Meredith
    11 hours ago











  • @KevinMeredith yeah, DDL >> triggers in my love list ;)

    – ypercubeᵀᴹ
    11 hours ago











  • So I don't need to add the check (max_length > 0) in customized_messages since it's already done in messages?

    – Kevin Meredith
    11 hours ago











  • Yes, the foreign key and the check constraint in messages guarantees that.

    – ypercubeᵀᴹ
    11 hours ago








  • 1





    Thanks! I'll accept in ~1 hour unless I see another answer (just to give time to other posters). Why is unique (id, max_length) needed though?

    – Kevin Meredith
    11 hours ago

















Do you like your proposal more than adding a trigger?

– Kevin Meredith
11 hours ago





Do you like your proposal more than adding a trigger?

– Kevin Meredith
11 hours ago













@KevinMeredith yeah, DDL >> triggers in my love list ;)

– ypercubeᵀᴹ
11 hours ago





@KevinMeredith yeah, DDL >> triggers in my love list ;)

– ypercubeᵀᴹ
11 hours ago













So I don't need to add the check (max_length > 0) in customized_messages since it's already done in messages?

– Kevin Meredith
11 hours ago





So I don't need to add the check (max_length > 0) in customized_messages since it's already done in messages?

– Kevin Meredith
11 hours ago













Yes, the foreign key and the check constraint in messages guarantees that.

– ypercubeᵀᴹ
11 hours ago







Yes, the foreign key and the check constraint in messages guarantees that.

– ypercubeᵀᴹ
11 hours ago






1




1





Thanks! I'll accept in ~1 hour unless I see another answer (just to give time to other posters). Why is unique (id, max_length) needed though?

– Kevin Meredith
11 hours ago





Thanks! I'll accept in ~1 hour unless I see another answer (just to give time to other posters). Why is unique (id, max_length) needed though?

– Kevin Meredith
11 hours ago


















draft saved

draft discarded




















































Thanks for contributing an answer to Database Administrators Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f227512%2fhow-to-add-check-constraint-between-tables-or-change-ddl%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

SQL Server 17 - Attemping to backup to remote NAS but Access is denied

Always On Availability groups resolving state after failover - Remote harden of transaction...

Restoring from pg_dump with foreign key constraints