tags:

views:

48

answers:

4

I want a column from a table to have a limited domain, which is listed in a different table. Usually, I'd just do this:

ALTER TABLE Table1
ADD CONSTRAINT FK_Especialidade FOREIGN KEY (column1)
REFERENCES Table2

However the values that "column1" must reference should not be a Primary Key in Table2. Any suggestions?

A: 

How about a trigger?

Jupe
+1  A: 

You could use a trigger (this is off the top of my head, the syntax might not be right...)

CREATE TRIGGER MyTrigger ON Table1 FOR INSERT, UPDATE
AS
  IF UPDATE(column1)
  BEGIN
    IF NOT EXIST (SELECT column2 FROM Table2 WHERE column2 = column1)
      RAISERROR ('Invalid column1 value.', 16, 1)
    END
  END

Make sure you at least have an index on column2 in Table2, you want your triggers to execute as fast as possible!

Dean Harding
A: 

A foreign key can reference any UNIQUE constraint in the target table, not just the primary key.

CREATE TABLE foo (
  foo_id INT PRIMARY KEY,
  some_attribute INT,
  UNIQUE KEY (some_attribute)
);

CREATE TABLE bar (
  bar_id INT PRIMARY KEY,
  some_attribute INT,
  FOREIGN KEY (some_attribute) REFERENCES foo (some_attribute) 
);
Bill Karwin
A: 

You've only added a 'SQL' tag so here's some valid full SQL-92:

ALTER TABLE Table1
ADD CONSTRAINT ck_Especialidade 
CHECK (
       EXISTS (
               SELECT * 
                 FROM Table2 
                WHERE Table2.column1 = Table1.column1
              )
      );

Of course, not all SQL products implement this full SQL-92 feature (e.g. SQL Server doesn't...) though there may be a workaround (... e.g. employing a user defined function). Anyhow, why reinvent the wheel?

onedaywhen
@onedaywhen - Do any RDBMSs actually implement this?
Martin Smith
I tested it using the Access Database Engine, though whether you consider this to be a RDBMSs I do not know. SQL products I know do not support it are SQL Server, Oracle, Mimer and Postgre.
onedaywhen
@onedaywhen So even though the constraint is on Table1 it will check when you delete something from Table2 whether that would violate the constraint?
Martin Smith
A constraint (or trigger, for that matter) is definied at the table level, so an update to another table will not cause it to be checked (fire). For such schema level constraints you need the Full SQL-92 `CREATE ASSERTION` and I know of no product that implements that.
onedaywhen