Subject | Re: [firebird-support] Constraint Problem |
---|---|
Author | Helen Borrie |
Post date | 2009-05-19T14:41:23Z |
At 10:17 PM 19/05/2009, you wrote:
1. Perform structural changes - that's *any* DDL - with exclusive access, as Owner of the object, in their own transactions and commit immediately.
2. Follow up immediately with any requisite DML (like your population of a non-nullable new column) in its own transaction and commit immediately.
3. When there is existing data, always be prepared to catch exceptions, interpret them and provide appropriate action (roll back and step back).
Note, if you're planning to impose referential integrity constraints then there is potential for existing data to be in violation. For this type of task, there's a Step Zero: to check and fix up data in columns that will be involved in the constraints - and commit the work before you proceed to Step 1, of course!
./heLen
>I have a table called "Readers" in a Firebird 2.1 database (FlameRobin...and COMMIT the transaction as soon as it has performed the DDL? This is essential, before you proceed to perform any DML on the existing rows.
>reports the server version as "WI-V2.1.0.17798 Firebird 2.1"). In the
>latest version of the front-end software driving this database I update
>the table using the following SQL:
>
>ALTER TABLE "Readers" ADD "AlwaysMonitor" SMALLINT NOT NULL;
>Since the field (like others in the table) must not be NULL, theAt best at this point (hoping you *did* commit the transaction that performed the DDL before you tried to update the data), you have a transaction with uncommitted DML. As long as it is uncommitted, it remains visible only to the transaction that performed it. That's a problem for you if you don't understand that that is how a transactional database system is designed to behave.
>front-end software then updates all existing records to have a value of
>0, and this update is successful (no errors are reported, and FlameRobin
>shows the field as being set to 0, not NULL).
>However, if I then try to update any other field, I get an errorDifferent transactions. An INSERT is not an update. However, the other transactions are aware that the new column and its constraint exist, so the validation fails in the newer transactions in order to preempt an inconsistent state.
>reported. DAO reports it as error 3197, but FlameRobin reports:
>
>The insert failed because a column definition includes validation
>constraints.
>Engine Code: 335544347
>Engine Message:
>validation error for column AlwaysMonitor, value "***null***".
>The problem is that AlwaysMonitor isn't NULL; it's 0.To the later transactions, it is still null.
> Note also thatLessons learnt: totally separate DDL from DML; perform *and commit* essential DML (such as populating constrained new columns) *before* admitting access to other transactions; exceptions ultimately are the way that the database protects the consistency of data state and interpreting them is a vital part of application design and workflow.
>there is no error message reporting other similarly constrained fields
>as being set to NULL. However, if I edit the value of AlwaysMonitor
>(eg I change it from 0 to 1), and then change whatever field I really
>wanted to change, all is OK; I can even change the value of
>AlwaysMonitor back to 0 afterwards.
>The front-end software is able to work with other database servers. ItThis isn't MySQL: it's an ACID-compliant, transactional database management system. The MySQL you're talking about is not ACID-compliant and can't protect itself from consistency violations; and it's non-transactional. (Some of its non-free backends do both consistency protection and transactions, however.)
>modifies the "Readers" table using the same method when working with
>MySQL (the only difference being the delimiters in the SQL), and
>everything works as intended.
>Can anyone tell me please why Firebird is having problems with thisLearn to appreciate the importance of consistency and it will become clearer why MySQL's behaviour has led to your misconception that consistency violation exceptions are "problems to be worked around".
>table modification, and more importantly, what I should do about it?
>I need to modify other tables in a similar way, so the clunky workaround IClunky workarounds to fix avoidable problems are not a safe practice at all. Stick to the road and watch for the signposts!
>discovered is not really an option.
1. Perform structural changes - that's *any* DDL - with exclusive access, as Owner of the object, in their own transactions and commit immediately.
2. Follow up immediately with any requisite DML (like your population of a non-nullable new column) in its own transaction and commit immediately.
3. When there is existing data, always be prepared to catch exceptions, interpret them and provide appropriate action (roll back and step back).
Note, if you're planning to impose referential integrity constraints then there is potential for existing data to be in violation. For this type of task, there's a Step Zero: to check and fix up data in columns that will be involved in the constraints - and commit the work before you proceed to Step 1, of course!
./heLen