repost of how to do select in a constraint

Started by Dennis Gearonabout 23 years ago7 messagesgeneral
Jump to latest
#1Dennis Gearon
gearond@cvc.net

I did not get an answer to my question, and I have RTFM'd all six
manuals at this point, so I will try the question again.

I have two tables one essentially a subset of the main table. The subset
adds criteria to the subset of rows from the main table that are
identified by their 'type_id'. The 'type_id' is from another table which
as a Foreign key.

'Orgs' is the main table,
'OrgTypes' is what it says it is, and
'MeetGrpDescs' is the subset table, only for
Orgs of type 'Group'

I'd like to create a table constraint, a trigger, a rule, whatever that
would
prevent insertion or updates of a row that had any other type besides:

'Group'

Into the table 'MeetGrpDescs'. I don't want to hardcode in the 'org_id'
value,
I'd like to put something like a join on org_type_id and then test if
org_type = 'Group'.

How can I do this? Thank you in advance.

-------------Schema of the tables involved (simplified)---------------

CREATE TABLE OrgTypes(
org_type_id serial NOT NULL, -- surrogate primary key of this table
org_type varchar(32) NOT NULL,
-- values will be 'Group','District','Area','Nation' hierarchally
CONSTRAINT PK_OrgTypes1 PRIMARY KEY (org_type_id),
CONSTRAINT UC_OrgTypes1 UNIQUE(org_type));

CREATE TABLE Orgs(
org_id serial NOT NULL, -- surrogate primary key of this table
org_type_id int4 NOT NULL,
org_name varchar(64) NOT NULL,
CONSTRAINT FK_Orgs_1 FOREIGN KEY (org_type_id)
REFERENCES OrgTypes (org_type_id),
CONSTRAINT PK_Orgs1 PRIMARY KEY (org_id,org_type_id),
CONSTRAINT UC_Orgs2 UNIQUE(org_name));

CREATE TABLE MeetGrpDescs( -- only Orgs of type 'Group' Allowed
org_id int4 NOT NULL,
org_type_id int4 NOT NULL,
special_notes text DEFAULT 'none' NOT NULL,
mail_returned bool DEFAULT 0 NOT NULL,
CONSTRAINT FK_MeetGrpDescs_3 FOREIGN KEY (org_id,org_type_id)
REFERENCES Orgs (org_id,org_type_id),
CONSTRAINT UC_Groups2 UNIQUE(org_id));

--

Carpe Dancem ;-)
-----------------------------------------------------------------
Remember your friends while they are alive
-----------------------------------------------------------------
Sincerely, Dennis Gearon

#2Peter Gibbs
peter@emkel.co.za
In reply to: Dennis Gearon (#1)
Re: repost of how to do select in a constraint

Dennis Gearon wrote:

I'd like to create a table constraint, a trigger, a rule, whatever that
would
prevent insertion or updates of a row that had any other type besides:

'Group'

Into the table 'MeetGrpDescs'. I don't want to hardcode in the 'org_id'
value,
I'd like to put something like a join on org_type_id and then test if
org_type = 'Group'.

Check constraints apparently cannot contain subselects, but they can contain
function calls, so how about something like:

CREATE FUNCTION org_type(int4) RETURNS text AS '
select org_type from OrgTypes where org_type_id = $1;
' LANGUAGE sql;

ALTER TABLE MeetGrpDescs
ADD CONSTRAINT GroupsOnly CHECK(org_type(org_type_id) = 'Group');

--
Peter Gibbs
EmKel Systems

#3Dennis Gearon
gearond@cvc.net
In reply to: Peter Gibbs (#2)
Re: repost of how to do select in a constraint

So, the constraint would only check what's being UPDATE'd or INSERT'd, so therefore only a
single value for org_type_id from the INSERT/UPDATE statement would be passed to the function,
correct?

1/20/2003 11:04:35 PM, "Peter Gibbs" <peter@emkel.co.za> wrote:

Show quoted text

Dennis Gearon wrote:

I'd like to create a table constraint, a trigger, a rule, whatever that
would
prevent insertion or updates of a row that had any other type besides:

'Group'

Into the table 'MeetGrpDescs'. I don't want to hardcode in the 'org_id'
value,
I'd like to put something like a join on org_type_id and then test if
org_type = 'Group'.

Check constraints apparently cannot contain subselects, but they can contain
function calls, so how about something like:

CREATE FUNCTION org_type(int4) RETURNS text AS '
select org_type from OrgTypes where org_type_id = $1;
' LANGUAGE sql;

ALTER TABLE MeetGrpDescs
ADD CONSTRAINT GroupsOnly CHECK(org_type(org_type_id) = 'Group');

--
Peter Gibbs
EmKel Systems

#4Peter Gibbs
peter@emkel.co.za
In reply to: Dennis Gearon (#3)
Re: repost of how to do select in a constraint

Dennis Gearon wrote:

So, the constraint would only check what's being UPDATE'd or INSERT'd, so

therefore only a

single value for org_type_id from the INSERT/UPDATE statement would be

passed to the function,

correct?

Correct.
--
Peter Gibbs
EmKel Systems

#5Dennis Gearon
gearond@cvc.net
In reply to: Peter Gibbs (#2)
Re: repost of how to do select in a constraint

Can I reference a function in a column check constraint, when the function doesn't yet exist,
i.e. a the time of table creation?

Or is it better to make the table, create the function, then alter table with a check
constraint?

#6Peter Gibbs
peter@emkel.co.za
In reply to: Dennis Gearon (#5)
Re: repost of how to do select in a constraint

Dennis Gearon wrote:

Can I reference a function in a column check constraint, when the function

doesn't yet exist,

i.e. a the time of table creation?

Or is it better to make the table, create the function, then alter table

with a check

constraint?

The function has to exist before the constraint is created. If the function
depends on the table that will have the constraint, you will need to add the
constraint afterwards; however, if the function only depends on other
tables, then you can create the function before creating the table.
--
Peter Gibbs
EmKel Systems

#7Dennis Gearon
gearond@cvc.net
In reply to: Peter Gibbs (#6)
Re: repost of how to do select in a constraint

Thank you VERY, VERY much. Since I am in the planning stages of the database, and don't have
it sited yet, these few questions that I might be able to answer by playing around on a
database hold me up. By answering them, you on this list, Peter in particular, have really
moved my development forward.

1/21/2003 10:11:41 PM, "Peter Gibbs" <peter@emkel.co.za> wrote:

Show quoted text

Dennis Gearon wrote:

Can I reference a function in a column check constraint, when the function

doesn't yet exist,

i.e. a the time of table creation?

Or is it better to make the table, create the function, then alter table

with a check

constraint?

The function has to exist before the constraint is created. If the function
depends on the table that will have the constraint, you will need to add the
constraint afterwards; however, if the function only depends on other
tables, then you can create the function before creating the table.
--
Peter Gibbs
EmKel Systems