Subject | Re: [firebird-support] Re: Checking periods don't overlap |
---|---|
Author | Martijn Tonies |
Post date | 2004-06-14T21:29:20Z |
Hi John,
CREATE TABLE UN_TEST
(
PKCOL INTEGER NOT NULL,
UNIQUE_COL INTEGER NOT NULL,
CONSTRAINT PK_UN_TEST PRIMARY KEY (PKCOL)
);
ALTER TABLE UN_TEST ADD CONSTRAINT C_UN_TEST
CHECK (
not exists (select ut.* from UN_TEST ut where new.UNIQUE_COL = ut.UNIQUE_COL
and ut.PKCOL <> new.PKCOL)
);
Note: the "new.PKCOL" works because it's internally a trigger :-)
And this:
INSERT INTO UN_TEST
( PKCOL
, UNIQUE_COL )
VALUES
( 3
, 3)
And do the same in a second transaction, I get a:
lock conflict on no wait transaction violation of PRIMARY or UNIQUE KEY
constraint "PK_UN_TEST" on table "UN_TEST"
If I commit the first, I cannot commit the second:
Operation violates CHECK constraint C_UN_TEST on view or table UN_TEST
Hmmm wait - now I see what you mean... I can do a "3, 4" and a "4,4" --
that's wrong.
Guess the constraint is wrong then :-)
Or the transaction isolation is ... here, I'm using READ COMMITTED, NO WAIT.
Ann, Helen, can someone help? :-)
With regards,
Martijn Tonies
Database Workbench - developer tool for InterBase, Firebird, MySQL & MS SQL
Server.
Upscene Productions
http://www.upscene.com
> Well, the thing about unique indexes and PK's is that they'll dirtySure they do. That's the whole idea.
> read, and see uncommitted conficts. You'll get an exception and know
> something went wrong before you get anywhere near a 'commit'.
>
> The constraints don't ensure the committed data is correct!
>They canNow, with this:
> ensure the record is internally consistent, and (thanks to you
> showing me how!) they can ensure the new record is valid against
> other committed records (as can a trigger for more complex
> situations). But they don't address the problem of other
> *uncommitted* records. Which will of course (usually) be committed
> later.
>
> Take that 'unique integer' check constraint I posted before:
>
> Transaction 1:
> insert into T values (1); /* no check violation */
>
> Transaction 2:
> insert into T values (1); /* can't see above, no violation */
>
> Trans 1:
> commit
>
> Trans 2:
> commit
>
> and you've violated your check constraint without an error!!
>
> Obviously if I wanted unique integers I'd use an index, but for the
> time period thing that's not easy.
>
> Unique Indexes work because they dirty-read. I just want check
> constraints to do the same!
CREATE TABLE UN_TEST
(
PKCOL INTEGER NOT NULL,
UNIQUE_COL INTEGER NOT NULL,
CONSTRAINT PK_UN_TEST PRIMARY KEY (PKCOL)
);
ALTER TABLE UN_TEST ADD CONSTRAINT C_UN_TEST
CHECK (
not exists (select ut.* from UN_TEST ut where new.UNIQUE_COL = ut.UNIQUE_COL
and ut.PKCOL <> new.PKCOL)
);
Note: the "new.PKCOL" works because it's internally a trigger :-)
And this:
INSERT INTO UN_TEST
( PKCOL
, UNIQUE_COL )
VALUES
( 3
, 3)
And do the same in a second transaction, I get a:
lock conflict on no wait transaction violation of PRIMARY or UNIQUE KEY
constraint "PK_UN_TEST" on table "UN_TEST"
If I commit the first, I cannot commit the second:
Operation violates CHECK constraint C_UN_TEST on view or table UN_TEST
Hmmm wait - now I see what you mean... I can do a "3, 4" and a "4,4" --
that's wrong.
Guess the constraint is wrong then :-)
Or the transaction isolation is ... here, I'm using READ COMMITTED, NO WAIT.
Ann, Helen, can someone help? :-)
With regards,
Martijn Tonies
Database Workbench - developer tool for InterBase, Firebird, MySQL & MS SQL
Server.
Upscene Productions
http://www.upscene.com