Probably the following might work
currentproject.connection.execute _
"ALTER TABLE myTable " & _
"ADD CONSTRAINT myTable_Check_A_differs_from_any_B " & _
"CHECK (A NOT IN (SELECT B FROM myTable))", , _
adcmdtext + adexecutenorecords
Good to see a CHECK constraint around here <g> but I don't think this
one does the job.
Consider:
CREATE TABLE myTable (
A INTEGER NOT NULL UNIQUE,
B INTEGER)
;
ALTER TABLE myTable ADD
CONSTRAINT myTable_Check_A_differs_from_any_B
CHECK (A NOT IN (SELECT B FROM myTable))
;
INSERT INTO myTable (A, B) VALUES (1, 2)
;
INSERT INTO myTable (A, B) VALUES (3, 1)
;
The CHECK does not bite after the second insert and the statement "A
differs from any B" is no longer true for the first inserted row. I
think that with the construt you've used the value of A only for the
inserted row(s) is checked.
This is the sort of constraint I'd write as an 'assertion' (the
resemblance to standard SQL's CREATE ASSERTION is not coincidental),
usually using a NOT EXISTS i.e. "there should never exist rows in this
state" kind of statement.
Consider:
DELETE FROM myTable
;
ALTER TABLE myTable DROP
CONSTRAINT myTable_Check_A_differs_from_any_B
;
ALTER TABLE myTable ADD
CONSTRAINT myTable_Check_A_differs_from_any_B
CHECK (
0 = (
SELECT *
FROM myTable AS T1, myTable AS T2
WHERE T1.A = T2.B))
;
INSERT INTO myTable (A, B) VALUES (1, 2)
;
INSERT INTO myTable (A, B) VALUES (3, 1)
;
This time the CHECK bites.
I originally used
ALTER TABLE myTable ADD
CONSTRAINT myTable_Check_A_differs_from_any_B CHECK (
NOT EXISTS (
SELECT *
FROM myTable AS T1, myTable AS T2
WHERE T1.A = T2.B))
;
but I get a funky 'No record' error when the CHECK is checked - pretty
useless, then.
The 0 = COUNT(*) approach is not preferred: NOT EXISTS should (I hope)
short circuit, plus COUNT with a nullable column takes some thought
hence is a maintenance issue (hint: COUNT(*)...GROUP BY will group and
count the null values).
Jamie.
--