How to create connection between two tables in SQL Server 2008? - sql-server

I have database that has Student table with information about each student in the system. Each record in that table has unique identifier that was created with NEWID() in SQL 2008. Then I have three other tables that use the same ID to link the student and the record. I'm wondering if I need to set any kind of property that will link these tables/records. Here is example of my Student table:
st_id -> Auto increment id
st_studentGUID -> Primary key
st_firstName
st_lastName
st_dob
st_gender
st_uid
st_udt
st_utime
And here is example of my other three tables:
Table 1 Table 2 Table 3
tb1_id -> auto increment tb2_id -> auto increment tb3_id -> auto increment
tb1_studentGUID tb2_studentGUID tb3_studentGUID
I have tried to create foreign key for each Table 1,2 and 3 on studentGUID but I got an error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Table1_Student". The conflict occurred in database "testDB", table "Student", column 'st_studentGUID'.
After I have done some research seems like this error occurred because Table 1 doesn't have all st_studentGUID. This make sense because student record might exist in Table 3 but not in Table 1. I'm wondering if there is any other sort of relation that I can set between the tables? Should I maybe use the Indexes on studentGUID fields? This is the reason why I'm asking this, in one of my update queries I use auto incremented id in where clause and for some reason I received an error that looks like this:
ErrorCode 1205
Message [Macromedia][SQLServer JDBC Driver][SQLServer]Transaction (Process ID 111) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
SQLState 40001
and error was pointing to the line that is end of the update query that looks like this:
<cfquery name="updateTable1" datasource="testDB">
UPDATE Table1
SET
tb1_testdt = <cfqueryparam value="#FORM.frm_testdt#" cfsqltype="cf_sql_date" maxlength="10" null="#yesNoFormat(!len(FORM.frmhs_testdtgr))#" />
FROM Table1 AS Table
LEFT OUTER JOIN studentLocked AS Locked
ON Locked.lk_studentGUID = Table.tb1_studentGUID
WHERE tb1_id = <cfqueryparam value="#FORM.frm_id#" cfsqltype="cf_sql_integer" />
AND lk_active = '1'
AND lk_staffID = <cfqueryparam value="#trim(appStaff)#" cfsqltype="cf_sql_char" maxlength="10" />
</cfquery>
Query above is checking if studentGUID exists in Lock table, reason why I'm doing this is because we do not want two different users updating the same record at the same time. Query updates single record and should be pretty fast. I'm confused whit the error message above deadlock victim. Is there something in my database design that is off or my update query is causing this error? I couldn't find anything on the web that could help me fix this issue. if anyone has experience with this kind of problem please let me know.

If all StudentGUIDs exist in the Student table, then the correct design is to have the StudentGUID in Table1, Table2 and Table3 be a Foreign Key to the Student table.

Now that you've sorted out your foreign key issue with the missing record from Student, try setting up your FKs on all of your tables, then re-try your update query.
If the deadlock issue persists and is reproducible, submit a new question for that, including the schema for the table you're updating and the values you're trying to pass.

Here's a script that demonstrates you can create the relationships you described provided all the keys are present in the students table:
CREATE TABLE students (st_id AS NEWID(),
st_studentGUID UNIQUEIDENTIFIER PRIMARY KEY)
INSERT INTO students (st_studentGUID) VALUES ('3B9F59DD-BF0A-4A09-BF4E-A396E2978B24')
INSERT INTO students (st_studentGUID) VALUES ('7CC5FF67-DAB8-426A-B9F7-E9F041718B6B')
INSERT INTO students (st_studentGUID) VALUES ('84B80D3E-44C4-4291-857D-B6CA6552369D')
CREATE TABLE t1 (tb1_id AS NEWID(), tb1_studentGUID UNIQUEIDENTIFIER)
ALTER TABLE t1
ADD CONSTRAINT FK_t1_tbl_studentGUID FOREIGN KEY (tb1_studentGUID) REFERENCES students(st_studentGUID)
INSERT INTO t1 (tb1_studentGUID) VALUES ('3B9F59DD-BF0A-4A09-BF4E-A396E2978B24')
CREATE TABLE t2 (tb2_id AS NEWID(), tb2_studentGUID UNIQUEIDENTIFIER)
ALTER TABLE t2
ADD CONSTRAINT FK_t2_tbl_studentGUID FOREIGN KEY (tb2_studentGUID) REFERENCES students(st_studentGUID)
INSERT INTO t2 (tb2_studentGUID) VALUES ('7CC5FF67-DAB8-426A-B9F7-E9F041718B6B')
CREATE TABLE t3 (tb3_id AS NEWID(), tb3_studentGUID UNIQUEIDENTIFIER)
ALTER TABLE t3
ADD CONSTRAINT FK_t3_tbl_studentGUID FOREIGN KEY (tb3_studentGUID) REFERENCES students(st_studentGUID)
INSERT INTO t3 (tb3_studentGUID) VALUES ('84B80D3E-44C4-4291-857D-B6CA6552369D')
Now create a 4th table, add a UUID that isn't in the students table, and try to create the foreign key constraint:
CREATE TABLE t4 (tb4_id AS NEWID(), tb4_studentGUID UNIQUEIDENTIFIER)
INSERT INTO t4 (tb4_studentGUID) VALUES ('897925F1-BE92-44EB-82C3-88E1C33C7792')
ALTER TABLE t4
ADD CONSTRAINT FK_t4_tbl_studentGUID FOREIGN KEY (tb4_studentGUID) REFERENCES students(st_studentGUID)
Which reproduces your error message:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_t4_tbl_studentGUID". The conflict occurred in database "IconERP", table "dbo.students", column 'st_studentGUID'.

Related

Insert/Update, ignore rows which would violate FK

If someone performs an update or insert on a table which has a foreign key to another, if a nonexistent value appears, an error is thrown. Is there an automated enough way to just ignore the faulty columns and continue with the others?
I can only think of an instead-of trigger, but it sounds messy.
You should check the rows in your INSERT query, by joining the source data with the referenced table.
For example, let's suppose that you have the following data in the SourceData table and you want to insert it in the Sales.CurrencyRate table in the AdventureWorks2019 database:
CREATE TABLE SourceData (
CurrencyRateDate datetime,
FromCurrencyCode char(3),
ToCurrencyCode char(3),
PRIMARY KEY (CurrencyRateDate, FromCurrencyCode, ToCurrencyCode),
Rate money NOT NULL
)
INSERT INTO SourceData (CurrencyRateDate, FromCurrencyCode, ToCurrencyCode, Rate) VALUES
('20200429','EUR','RON',4.8425),
('20200429','EUR','ROL',48425),
('20200430','EUR','RON',4.8421),
('20200430','EUR','ROL',48421)
INSERT INTO Sales.CurrencyRate (CurrencyRateDate, FromCurrencyCode, ToCurrencyCode, AverageRate, EndOfDayRate)
SELECT sd.CurrencyRateDate, sd.FromCurrencyCode, sd.ToCurrencyCode, sd.Rate, sd.Rate
FROM SourceData sd
If you simply run the INSERT statement mentioned above, you would get an error saying "The INSERT statement conflicted with the FOREIGN KEY constraint "FK_CurrencyRate_Currency_ToCurrencyCode". The conflict occurred in database "AdventureWorks2019", table "Sales.Currency", column 'CurrencyCode'.", because the currency "RON" is not present in the Sales.Currency table.
To avoid this error and insert only the data that has corresponding rows in the referenced table, you would simply use a JOIN for each FK, like this:
INSERT INTO Sales.CurrencyRate (CurrencyRateDate, FromCurrencyCode, ToCurrencyCode, AverageRate, EndOfDayRate)
SELECT sd.CurrencyRateDate, sd.FromCurrencyCode, sd.ToCurrencyCode, sd.Rate, sd.Rate
FROM SourceData sd
INNER JOIN Sales.Currency c1 ON c1.CurrencyCode=sd.FromCurrencyCode
INNER JOIN Sales.Currency c2 ON c2.CurrencyCode=sd.ToCurrencyCode

SQL Server foreign key contsraint preventing insert, where no conflict exits

I have 2 tables, and I have just done an insert of about 1,000,000 rows. I turned off foreign key constraints , but I have an error when I try and reinstate them with
ALTER TABLE ForexRebatesNow.dbo.Transactions WITH CHECK CHECK CONSTRAINT ALL
I get the following error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Transactions_RebateAccounts". The conflict occurred in database "ForexRebatesNow", table "dbo.RebateAccounts", column 'Id'.
So I go to look for RebateAccountId that does not have a corresponding Id in the RebateAccounts table
SELECT Id
FROM ForexRebatesNow.dbo.RebateAccounts
WHERE Id NOT IN (SELECT RebateAccountId
FROM ForexRebatesNow.dbo.Transactions)
But this returns zero rows, so in my mind that conflict does not exist.
Am I missing something here?
EDIT
The relationship between RebateAccounts and Transactions is One to Many. RebateAccountId is a Nullable int on Transactions table as not allTransactions will have an associated RebateAccount, but any RebateAccount can have many Transactions
As you have not provided the relations between the two tables, I assume that there is a One-to-Many relation between RebateAccounts and Transactions Table. If I'm right then I guess you are checking the conflict in an opposite way. Your foreign key in in the dbo.Transactions table but you are checking it with the dbo.RebateAccounts table.
Try the following query to find the conflict.
SELECT * FROM Transactions WHERE RebateAccountId NOT IN (SELECT Id FROM RebateAccounts)
If any row shows up then that row has an account id that does not belong to any account. That's where your conflict is.
Hope it helps.

Insert records from one table to another without violating any constraint in SQL Server database

There are 2 databases DB_Main and DB_Backup in SQL Server 2008.
I want to copy the data of Table1 from DB_Backup into Table1 of DB_Main.
The structure of all the tables in both the database is same. Both the tables in both the database have foreign key, primary key constraint.
When I try to copy data of Table1 from DB_Backup into Table1 of DB_Main with this query:
Insert into [DB_Main].[Table1]
Select *
from [DB_Backup].[Table1];
I get this foreign key error.
The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_Table1_Table3". The conflict occurred in database "DB_Main",
table "Table3", column 'RequestID'.
Please let me know any simple way to copy all the records of Table1 from DB_Backup into Table1 of DB_Main, without violating any constraint?
Please reply
What this means is that for example you are trying to insert a record into Table1 which has for example RequestID = 75. The foreign key constraint means that there must be a record with RequestID = 75 in Table3.... and there currently isn't.
So this means you also need to load data into Table3
To find the records actually causing the issue run
Select DISTINCT RequestID from [DB_Backup].[Table1]
Some of these request ID's need a 'parent' record in Table3
To find the specific ones run
Select RequestID from [DB_Main].[Table3]
WHERE Request_ID NOT IN (
Select DISTINCT RequestID from [DB_Backup].[Table1]
)
You need to insert these into Table3:
insert into Table3(Request_ID, OtherColumn)
Select RequestID, OtherColumn from [DB_Backup].[Table3]
WHERE Request_ID NOT IN (
Select DISTINCT RequestID from [DB_Main].[Table3]
)
Then you can load your other records.
Drop or Disable constraint FK_Table1_Table3 before inserting and enable after it.
To Disable:
ALTER TABLE Table1 NOCHECK CONSTRAINT ALL
or
ALTER TABLE Table1 NOCHECK CONSTRAINT FK_Table1_Table3
Source
to Enable
ALTER TABLE Table1 CHECK CONSTRAINT ALL
or
ALTER TABLE Table1 CHECK CONSTRAINT FK_Table1_Table3

Do Foreign Key constraints get checked on an SQL update statement that doesn't update the columns with the Constraint?

Do Foreign Key constraints get checked on an SQL update statement that doesn't update the columns with the Constraint? (In MS SQL Server)
Say I have a couple of tables with the following columns:
OrderItems
- OrderItemID
- OrderItemTypeID (FK to a OrderItemTypeID column on another table called OrderItemTypes)
- ItemName
If I just update
update [dbo].[OrderItems]
set [ItemName] = 'Product 3'
where [OrderItemID] = 2508
Will the FK constraint do it's lookup/check with the update statement above? (even thought the update is not change the value of that column?)
No, the foreign key is not checked. This is pretty easy to see by examining the execution plans of two different updates.
create table a (
id int primary key
)
create table b (
id int,
fkid int
)
alter table b add foreign key (fkid) references a(id)
insert into a values (1)
insert into a values (2)
insert into b values (5,1) -- Seek on table a's PK
update b set id = 6 where id = 5 -- No seek on table a's PK
update b set fkid = 2 where id = 6 -- Seek on table a's PK
drop table b
drop table a
No. Since the SQL update isn't updating a column containing a constraint, what exactly would SQL Server be checking in this case? This is similar to asking, "does an insert trigger get fired if I only do an update?" Answer is no.
There is a case when the FK not existing will prevent updates to other columns even though the FK is not changed and that is when the FK is created WITH NOCHECK and thus not checked at the time of creation. Per Books Online:
If you do not want to verify new CHECK or FOREIGN KEY constraints
against existing data, use WITH NOCHECK. We do not recommend doing
this, except in rare cases. The new constraint will be evaluated in
all later data updates. Any constraint violations that are suppressed
by WITH NOCHECK when the constraint is added may cause future updates
to fail if they update rows with data that does not comply with the
constraint.

delete from two table having foreign key constraint

I have two tables in my database and the t1 table primary key is uid, t2 table a foreign key name desg. now I want to delete or update this uid in one table give error that
Now row was updated. data in the row
was not committed. error
source:.netSqlclient data provider.
error message: the update statement
conflicted with the reference
constraint fk_t2_t1.the conflict occur
in the database DBname, dbo.t2,column
desg. the stsement has been
terminated.
and when I try to delete, it show this message.
executed SQl statement: delete from t1
where uid='abc'
error source:.netSqlclient data
provider. error message: the Delete
statement conflicted with the
reference constraint fk_t2_t1.the
conflict occur in the database DBname,
dbo.t2,column desg. the stsement has
been terminated.
Please tell me how to do this update and delete.
I am new to this field need help thanks in advances.
first delete the t2 table a foreign key then delete t1 table primary key is uid . this will work not vise versa
You have one or more child records in table t2 which are pointing at the master record in table t1 that you want to delete. Before you can delete your record in t1, you must delete the child records in t2.
For example:
(1) delete * from t2 where t2.desg = t1.uid;
(2) delete * from t1 where t1.uid = UID_TO_BE_REMOVED;
I would recommend reading a good reference on creating tables and performing queries for the SQL database you are using.
Good luck!

Resources