How to insert data with the cross-referenced tables? - sql-server

I have two tables. The table structure is given below.
CREATE TABLE t1
(
col1 int PRIMARY KEY,
col2 int REFERENCES t2(col4)
)
And
CREATE TABLE t2
(
col3 int PRIMARY KEY,
col4 int REFERENCES t1(col1)
)
Now how do I populate the tables using INSERT statement. I can do it by inserting a NULL value in the FOREIGN KEY COLUMN and then UPDATE that column. But I don't want to use the UPDATE statement. I want to do it using a INSERT statement.
How should I do it?

I sense a bad design decision here. If update is not an option, then disabling the constraint, inserting data and then re-enabling the constraint can be considered, but that is also an inherently bad approach, as the very purpose of enforcing those constraints in the first place is defeated.
Anyway, here is how:
ALTER TABLE t1 NOCHECK CONSTRAINT <YourFKConstraint>
ALTER TABLE t2 NOCHECK CONSTRAINT <YourFKConstraint>
GO
INSERT INTO t1
VALUES (1,1)
GO
INSERT INTO t2
VALUES (1,1)
GO
ALTER TABLE t1 CHECK CONSTRAINT <YourFKConstraint>
ALTER TABLE t2 CHECK CONSTRAINT <YourFKConstraint>
Please be warned that this approach will allow you to enter data that violates the constraint. Redesign would be the best option.

Related

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

Is it possible to ignore varchar length when setting foreign key between tables?

There are two tables in my SQL Server 2008.
CREATE TABLE TABLE1 (
field1 varchar(20) not null,
field2 int,
CONSTRAINT PK_TABLE1 PRIMARY KEY (field1)
)
CREATE TABLE TABLE2 (
Id int,
t1 varchar(10) not null
t2 ntext
CONSTRAINT PK_TABLE2 PRIMARY KEY (Id)
)
Now I want to build a foreign key on table2 with below command :
ALTER TABLE TABLE2
ADD CONSTRAINT TABLE2_FK
FOREIGN KEY (t1) REFERENCES TABLE1 (field1)
ON DELETE CASCADE ON UPDATE CASCADE
SQL Server responds that the foreign key in Table2 is different from the column field1 in Table1 in length.
Is it possible to ask SQL Server to ignore the validation of length of foreign key ?
Thank you for your answer.
No, it is not possible. From the MSDN page on CREATE TABLE, which includes a section about foreign keys:
The REFERENCES clause of a table-level FOREIGN KEY constraint must
have the same number of reference columns as the number of columns in
the constraint column list. The data type of each reference column
must also be the same as the corresponding column in the column list.
Of course, you can make a computed column that casts the VARCHAR(10) to a VARCHAR(20) and then set the foreign key.

Add primary key column in SQL table

I am student of RDBMS.
I have very basic question let say I have one existing Table in SQL server. What will be script to alter table.
Drop Column 'RowId' if exist.
Drop contraint if exist.
Add one new column 'RowId' into table.
Make this column as primary key.
Autoincrement type int.
In SQL Server 2005 or newer, you could use this script:
-- drop PK constraint if it exists
IF EXISTS (SELECT * FROM sys.key_constraints WHERE type = 'PK' AND parent_object_id = OBJECT_ID('dbo.YourTable') AND Name = 'PK_YourTable')
ALTER TABLE dbo.YourTable
DROP CONSTRAINT PK_YourTable
GO
-- drop column if it already exists
IF EXISTS (SELECT * FROM sys.columns WHERE Name = 'RowId' AND object_id = OBJECT_ID('dbo.YourTable'))
ALTER TABLE dbo.YourTable DROP COLUMN RowId
GO
-- add new "RowId" column, make it IDENTITY (= auto-incrementing)
ALTER TABLE dbo.YourTable
ADD RowId INT IDENTITY(1,1)
GO
-- add new primary key constraint on new column
ALTER TABLE dbo.YourTable
ADD CONSTRAINT PK_YourTable
PRIMARY KEY CLUSTERED (RowId)
GO
Of course, this script may still fail, if other tables are referencing this dbo.YourTable using foreign key constraints onto the pre-existing RowId column...
Update: and of course, anywhere I use dbo.YourTable or PK_YourTable, you have to replace those placeholder with the actual table / constraint names from your own database (you didn't mention what they were, in your question.....)
Note: this answer was added before questions update
Add new column (note: you can only have one IDENTITY column per table)
Drop old primary key
Add new primary key
Drop old column if needed
Sample script:
CREATE TABLE whatever (
OldPKColumn uniqueidentifier NOT NULL,
CONSTRAINT PK_whatever PRIMARY KEY (OldPKColumn)
)
ALTER TABLE whatever
ADD RowId int NOT NULL IDENTITY (1,1);
ALTER TABLE whatever
DROP CONSTRAINT PK_whatever;
ALTER TABLE whatever WITH CHECK
ADD CONSTRAINT PK_whatever PRIMARY KEY CLUSTERED (RowId);
ALTER TABLE whatever
DROP COLUMN oldPKcolumn;
And a random thought... are you trying to reset an IDENTITY column?
If so, then use DBCC CHECKIDENT
Just a comment to improve these great answers (can't use comments yet - I'm one reputation point away from that privilege) and as future reference for myself:
A new IDENTITY (autonumber) column can be added and made the primary key in a single statement as well:
ALTER TABLE [TableName] ADD [ColumnName] int IDENTITY PRIMARY KEY;
I prefer not to bother with constraint names when it doesn't help.
You can specify seed (and increment) values between parantheses after the IDENTITY keyword.

Ignore Duplicate Values on Index prevents FOREIGN KEY constraint

Due to some architectural reasons I have to ignore duplicate values on the index. It works perfectly well - except, when I am inserting wrong data. I am trying to insert value to the FK column that is supposed to throw:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK__constrainName".
The conflict occurred in database, table "someTable", column 'FKColumn'.
Is there logic behind ignoring duplicate values that prevents insert statement from throwing this exception?
I assume you are talking about this kind of situation?
CREATE TABLE T2(T2_ID INT PRIMARY KEY)
INSERT INTO T2 VALUES (1),(2)
CREATE TABLE T1 (T1_ID INT, T2_ID INT REFERENCES T2)
CREATE UNIQUE CLUSTERED INDEX IX ON T1(T1_ID) WITH IGNORE_DUP_KEY
INSERT INTO T1 VALUES (1,2),(1,2),(2,3),(2,3)
/*FK Violation - No rows inserted*/
SELECT *
FROM T1
/*Duplicate key violation and potential FK Violation - one row inserted*/
INSERT INTO T1 VALUES (1,2),(1,2),(1,3),(1,3)
SELECT *
FROM T1
DROP TABLE T1
DROP TABLE T2
If a row is not inserted because it would cause a duplicate key violation then the FK constraint is not violated following the insert, hence no error.

Fixing broken foreign keys with ALTER TABLE ... WITH CHECK CHECK CONSTRAINT

I have a broken foreign key in SQL Server 2005. Here is a reproduction:
CREATE TABLE t2(i2 BIGINT NOT NULL PRIMARY KEY)
CREATE TABLE t1(i1 BIGINT NOT NULL PRIMARY KEY)
ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (i1) REFERENCES t2 (i2)
ALTER TABLE t1 NOCHECK CONSTRAINT fk
INSERT INTO t1 (i1) VALUES (0)
If I subsequently run:
ALTER TABLE t1 WITH CHECK CHECK CONSTRAINT fk
I get the error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "fk". The conflict occurred in database "broken-fk", table "dbo.t2", column 'i2'.
I can fix this manually:
DELETE FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t2.i2 = t1.i1)
ALTER TABLE t1 WITH CHECK CHECK CONSTRAINT fk
but I'd prefer to do it in one step, as each presumably needs a table scan and the table is tens of gigabytes in size.
Is it possible to get the ALTER TABLE to fix the error (by dropping rows) rather than exiting with an error?
Thanks.
Is it possible to get the ALTER TABLE to fix the error
(by dropping rows) rather than exiting with an error?
The long and short - no.
Do it in two steps as you are familiar with.
You could stop at
ALTER TABLE t1 CHECK CONSTRAINT fk
which turns it on for new records but leaves the existing data alone?

Resources