Oracle SQL Foreign Key constraint that ignores null or historic values - sql

I am trying to add a constrain to a database table that I want to modify. I want to add a constraint on a column so it references a primary key of another tables. Easy enough, I just have to add a foreign key constraint. The problem is that the column already has some values that are null or something that is not part of the table I will be referencing.
My question is how do I add a constraint that references a primary key but can also accept null values (the primary key always has a value) and how to ignore the existing values so far. Is it possible? If the second part is not, I am thinking I could always write a script that updates all the nonsense values (they have a format of sort if that I can reg ex) to null so they only thing I have to figure out is how to add a foreign key constraind that also accepts null values

Firstly, there's nothing stopping you from adding a referential constraint on a column that has NULLs - foreign key constraints are only enforced for non-NULL values.
Secondly, if there are existing values that do not exist in the parent table, and you can't fix them, you do have the option in Oracle to make the constraint only validated for newly inserted or updated rows, using the NOVALIDATE option, e.g.
ALTER TABLE x ADD CONSTRAINT fk FOREIGN KEY (id) REFERENCES parent (id) NOVALIDATE;
The only downside to using the NOVALIDATE option is that the query optimizer will not rely on the FK constraint, and will execute queries with the assumption that there may be rows that do not have a matching parent row.
It would be a good idea if you are able to fix the missing values, afterwards to alter the constraint to VALIDATE.

Primary keys can not contain NULL values in all databases (proof)
To add a foreign key you should do something like:
ALTER TABLE table1
ADD CONSTRAINT fk_table1_2
FOREIGN KEY (column1)
REFERENCES table2(column2);

Related

MSSQL Foreign Key Relationship and Null values

I'm having problems adding a foreign key to an existing table where the foreign key can be null.
Say I have a user table and a data table. The data table already has a working foreign key on the "createdBy" colum to the user table ID column. I've just added a second column to the data table "EditedBy" that allows for null values (meaning the data record hasn't been edited). So all the existing records have NULL as the value for this column.
I am trying to make a foreign key between Data.EditedBy and User.Id, but when I try to apply it, I get the following error.
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Data_User_EditedBy". The conflict occurred in database "Test", table "dbo.User", column 'Id'.
It seems like its having a problem with the NULL values in the data table, but NULL is an acceptable value for a foreign key.
What am I missing?
UPDATE:
Full statement is as follows
USE [Test]
GO
ALTER TABLE [dbo].[Data] WITH CHECK ADD CONSTRAINT [FK_Data_User_EditedBy] FOREIGN KEY([Id])
REFERENCES [dbo].[User] ([Id])
GO
Ok, I feel like an idiot. I was using Management studio to create the relationship, and after I posted the equivalent alter statement (which didn't work either), I realized I was trying to make a foreign key between the ID field of [data] and the ID field of [user].
Obviously that wont work.
I fixed the statement to use the correct field in the [data] table and all is well.

column deleted, now want to add constraint back

I deleted a column in a table, using ALTER TABLE. I didn't realize that there was a constraint attached to it. Now the constraint also got deleted. How do I add the constraint back? I don't know the exact wording of that constraint. Also, the table was empty, so in that moment I thought the column was never going to be populated and removed it.
Here is the table CREATE query in pgadmin3:
CREATE TABLE employee_grade
(
id uuid NOT NULL DEFAULT uuid_generate_v4(),
graded_to uuid,
grade character varying(10),
graded_by uuid,
grade_date timestamp with time zone,
grade_month timestamp with time zone,
CONSTRAINT employee_grade_pkey PRIMARY KEY (id),
CONSTRAINT employee_grade_by_fk FOREIGN KEY (graded_by)
REFERENCES employee (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT employee_grade_to_fk FOREIGN KEY (graded_to)
REFERENCES employee (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
I don't know what the constraint was, but I do know that it involved the graded_by and graded_to foreign keys, and the grade_month column. It was also unique.
It probably meant that in that month, graded_by graded graded_to, and there should not be two gradings in the same month for the same two employees.
Also, if it helps, the corresponding Java entity does not have a corresponding gradeMonth column.
Turns out the answer indeed was a simple UNIQUE constraint:
CONSTRAINT grade_month_uniq UNIQUE (graded_to, graded_by, grade_month)
I used this and it works fine for the intended purpose.
Thanks #NickBarnes.

Why can't I add this foreign key?

I'll post only the main part. I have two tables, each one has to have the PK of the other as a FK.
CREATE TABLE apartment
(
cod_apartment INT NOT NULL PRIMARY KEY,
cod_offer INT NOT NULL
);
CREATE TABLE offer
(
cod_offer INT NOT NULL PRIMARY KEY,
cod_apartment INT NOT NULL
);
First I inserted the values on both tables and it was working, I could even search using "select * from...". But then I tried to add the foreign key:
This worked.
ALTER TABLE offer
ADD FOREIGN KEY (cod_apartment ) REFERENCES apartment;
And this not.
ALTER TABLE apartment
ADD FOREIGN KEY (cod_offer) REFERENCES offer;
This is the error message:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK__apartment__cod_offer__6383C8BA". The conflict occurred in database "kleber_apartment", table "dbo.offer", column 'cod_offer'.
The problem is, every time I try to execute, the FK name changes. And this FK actually doesn't exist. I already dropped both tables and tried to insert the values again, but the same happens.
What could be?
That means you're trying to add a foreign key when existing data doesn't obey that constraint. So you have a record in your apartment table where the cod_offer column does not match any value in the cod_apartment table.
Adding a foreign key not only constrains future data, but it requires that any existing data must also follow the rule.
And regarding the 6383C8BA, whenever you add a constraint without giving it a name, SQL Server picks one for you. Personally, I'd recommend something like:
alter table dbo.apartment
add constraint FK_apartment__cod_offer
foreign key (cod_offer) references dbo.offer (cod_offer);
This lets you define names the way you want, and is a little more clear about what you're actually building.

Adding Constraint with multiple foreign keys

I have a SQL database opened with visual studio, and I need to add some constraints to a table already created. I need a foreign key, which already has a foreign key from a third table. To explain better ,
Table ANIMALI needs a foreign key from table GABBIA, which has already a foreign key from table STANZA. This was the code I came up with:
ALTER TABLE ANIMALE ADD CONSTRAINT REF_ANIMA_GABBI_FK FOREIGN KEY (n_stanza, n_gabbia) REFERENCES GABBIA(n_stanza, n_gabbia);
This gives me an error, n_stanza is a column id not valid. I think it's about the fact that the ID for the class GABBIA is taken from joining n_gabbia and n_stanza, the latter being a key in class STANZA.
Can anyone help me out?
In order for your ALTER TABLE statement to work as written, both tables (not classes) "ANIMALE" and "GABBIA" must include the columns "n_stanza" and "n_gabbia".
In addition, in the table "GABBIA", there must be either a primary key constraint or a unique constraint on the pair of columns "n_stanza" and "n_gabbia". That is, you need something like either primary key (n_stanza, n_gabbia) or unique (n_stanza, n_gabbia) in the table "GABBIA".

Does a foreign key constraint automatically disallow nulls?

In my Activities table I have a StaffId field. This is a FK of the Staff table (that holds StaffId). On inserting data into the Activities table - if the StaffId is null it throws a FK constraint error!? I have ticked the 'Alllow Nulls' box in SSMS so why is this not the case?
Note, this record is being inserted through the DbCommand.ExecuteNonQuery method.
Also note: I have just ran an Insert statement using SSMS to insert NULL values, and it worked. May be this is a more C# specific question!?
No, look at this http://msdn.microsoft.com/en-us/library/ms175464.aspx
A FOREIGN KEY constraint does not have to be linked only to a PRIMARY
KEY constraint in another table; it can also be defined to reference
the columns of a UNIQUE constraint in another table. A FOREIGN KEY
constraint can contain null values; however, if any column of a
composite FOREIGN KEY constraint contains null values, verification of
all values that make up the FOREIGN KEY constraint is skipped. To make
sure that all values of a composite FOREIGN KEY constraint are
verified, specify NOT NULL on all the participating columns.
you can see another example in MySql, look at the following link http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
You can see that it is possible to SET NULL
SET NULL: Delete or update the row from the parent table and set the
foreign key column or columns in the child table to NULL. This is
valid only if the foreign key columns do not have the NOT NULL
qualifier specified. Both ON DELETE SET NULL and ON UPDATE SET NULL
clauses are supported.
If you specify a SET NULL action, make sure that you have not declared
the columns in the child table as NOT NULL.
It is possible to do on the DB as #Martin demonstrated. The problem is on your front end. DbCommand has issues dealing with NULLs, that's one of the reasons they created Linq To Sql.
I suggest you try something like this:
if(parameter_is_not_null)
db.AddInParameter(dbCommand, "staffId", DbType.String, staffId.Text);
else
db.AddInParameter(dbCommand, "staffId", DbType.String, DBNull.Value);