How to Add Check Constraint between Tables (or change DDL)?
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
add a comment |
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
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
add a comment |
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
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
postgresql check-constraints
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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.
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 thecheck (max_length > 0)
incustomized_messages
since it's already done inmessages
?
– 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 isunique (id, max_length)
needed though?
– Kevin Meredith
11 hours ago
|
show 1 more comment
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 thecheck (max_length > 0)
incustomized_messages
since it's already done inmessages
?
– 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 isunique (id, max_length)
needed though?
– Kevin Meredith
11 hours ago
|
show 1 more comment
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.
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 thecheck (max_length > 0)
incustomized_messages
since it's already done inmessages
?
– 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 isunique (id, max_length)
needed though?
– Kevin Meredith
11 hours ago
|
show 1 more comment
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.
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.
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 thecheck (max_length > 0)
incustomized_messages
since it's already done inmessages
?
– 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 isunique (id, max_length)
needed though?
– Kevin Meredith
11 hours ago
|
show 1 more comment
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 thecheck (max_length > 0)
incustomized_messages
since it's already done inmessages
?
– 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 isunique (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
|
show 1 more comment
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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