SQL Server - ALTER query can create FK relationships, but cannot view them? - sql-server

I'm stumped on whether I have written the correct syntax to create a foreign key.
I used SQL Server 2012 Express.
If I run a ALTER query to set a foreign key relationship between two table, it works fine, no errors occured. However, if I right-click the table where the FK was created, I don't see any relationships.
This is the ALTER query I have wrote. It creates a relationship between Employers and Employees with EmployerID as a FK.
USE demodemo;
BEGIN TRAN t1
ALTER TABLE Employees
WITH check
ADD CONSTRAINT Employees_EmployerID_FK FOREIGN KEY
(EmployerID) REFERENCES Employers(ID);
GO
The command was executed 'successfully'.
However, if I right click the table, Employees, and select 'Relationships'.
No foreign keys relationships can be seen.
I thought writing the above ALTER query would be the equivalent of creating a FK relationship via the 'Relationships' gui.
Despite having no issues in creating foreign key relationships, I just cannot see them at all.
What could I be doing wrong?
Is my ALTER query correct?
What is the ALTER syntax equivalent to allow me to view the "selected relationships"?

Your DML is missing COMMIT. Also, right click and refresh after executing the SQL
Raj

Related

Cannot create a relation between two tables with three primary keys

I recently used Microsoft SQL Server Migration Assistant for Oracle to convert an Oracle database to a SQL Server database through a two-pass approach.
There is are two tables, BILL_INFO and BILL_INFO_DETAIL, that are supposed to have a master-detail relation through composite PK. However, when I try to create that relation, I get this error:
'BILL_INFO' table saved successfully 'BILL_INFO_DETAIL' table
- Unable to create relationship 'FK_BILL_INFO_DETAIL_BILL_INFO'. The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
"FK_BILL_INFO_DETAIL_BILL_INFO". The conflict occurred in database
"MyDatabase", table "dbo.BILL_INFO".
The database is plagued with bad data. So I did a basic search in the detail table to find BILL_NUMBER, PAY_MODE_ID, and CASHIER_ID that may not exist in master (one by one) and found two records when searching on BILL_NUMBER. I fixed them and also verified that PAY_MODE_ID and CASHIER_ID were in order.
Still, I cannot create the relation. Same error. Now I wonder if the Tuple is invalid between tables. How do I find a composite key that exists only in details table?
You could check for non-existing values using:
SELECT bill_number, pay_mode_id, cashier_id
FROM Bill_Info_Detail
EXCEPT
SELECT bill_number, pay_mode_id, cashier_id
FROM Bill_Info;
-- and then fix missing data
When using composite key, you need to check all columns as tuple.

Remove record from sys.objects?

I ran a ALTER SCHEMA ... on a table (SQL Server 2012 SP1) but the sys.objects record is still there. When I run the ETL I get an error that the table doesn't exist anymore because it's trying to remove all constraints. This one is of type PK Primary Key Constraint. How can I safely remove the record from the sys.objects table?
I managed to fix this issue by scripting the database to a new one, ALTER SCHEMA ... again on that table to bring it back to dbo., then DROP and recreate the table in the different table schema.

Deleting a SQL row ignoring all foreign keys and constraints

I have a row in a table. This row has an ID column referenced in a few other tables with millions of rows. The SQL statement to delete the row always times out. From my design, I know the row I wish to delete is never referenced any where else. Hence I would like SQL to ignore having to check all other tables for a foreign key reference to this row and delete the row immediately. Is there a quick way to do this in SQL 2008?
Perhaps something along the lines of:
DELETE FROM myTable where myTable.ID = 6850 IGNORE CONSTRAINTS
Or something along those lines.
You can set the constraints on that table / column to not check temporarily, then re-enable the constraints. General form would be:
ALTER TABLE TableName NOCHECK CONSTRAINT ConstraintName
Then re-enable all constraints with
ALTER TABLE TableName CHECK CONSTRAINT ConstraintName
I assume that this would be temporary though? You obviously wouldn't want to do this consistently.
Yes, simply run
DELETE FROM myTable where myTable.ID = 6850
AND LET ENGINE VERIFY THE CONSTRAINTS.
If you're trying to be 'clever' and disable constraints, you'll pay a huge price: enabling back the constraints has to verify every row instead of the one you just deleted. There are internal flags SQL keeps to know that a constraint is 'trusted' or not. You're 'optimization' would result in either changing these flags to 'false' (meaning SQL no longer trusts the constraints) or it has to re-verify them from scratch.
See Guidelines for Disabling Indexes and Constraints and Non-trusted constraints and performance.
Unless you did some solid measurements that demonstrated that the constraint verification of the DELETE operation are a performance bottleneck, let the engine do its work.
Do not under any circumstances disable the constraints. This is an extremely stupid practice. You cannot maintain data integrity if you do things like this. Data integrity is the first consideration of a database because without it, you have nothing.
The correct method is to delete from the child tables before trying to delete the parent record. You are probably timing out because you have set up cascading deltes which is another bad practice in a large database.
I know this is an old thread, but I landed here when my row deletes were blocked by foreign key constraints. In my case, my table design permitted "NULL" values in the constrained column. In the rows to be deleted, I changed the constrained column value to "NULL" (which does not violate the Foreign Key Constraint) and then deleted all the rows.
I wanted to delete all records from both tables because it was all test data. I used SSMS GUI to temporarily disable a FK constraint, then I ran a DELETE query on both tables, and finally I re-enabled the FK constraint.
To disable the FK constraint:
expand the database object [1]
expand the dependant table object [2]
expand the 'Keys' folder
right click on the foreign key
choose the 'Modify' option
change the 'Enforce Foreign Key Constraint' option to 'No'
close the 'Foreign Key Relationships' window
close the table designer tab
when prompted confirm save changes
run necessary delete queries
re-enable foreign key constraint the same way you just disabled it.
[1] in the 'Object Explorer' pane, can be accessed via the 'View' menu option, or key F8
[2] if you're not sure which table is the dependant one, you can check by right clicking the table in question and selecting the 'View Dependencies' option.
This is the way to disable foreign key checks in MySQL. Not relevant to OP's question since they use MS SQL Server, but google search results do turn this up so here's for reference:
SET FOREIGN_KEY_CHECKS = 0;
/ Run your script /
SET FOREIGN_KEY_CHECKS = 1;
See if this helps, This is for ignoring the foreign key checks.
But deleting disabling this is very bad practice.
On all tables with foreign keys pointing to this one, use:
ALTER TABLE MyOtherTable NOCHECK CONSTRAINT fk_name
You can disable all of the constaints on your database by the following line of code:
EXEC sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
and after the runing your update/delete command, you can enable it again as the following:
EXEC sp_MSforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
You could maybe disable and re-enable constraints:
http://sqlforums.windowsitpro.com/web/forum/messageview.aspx?catid=60&threadid=48410&enterthread=y
For the testing purpose only, I used the following command in MySQL to delete only one record from a table that has foreign key references.
SET FOREIGN_KEY_CHECKS = 0; -- Disabling foreign key checks before running the following query.
DELETE FROM table_name WHERE id = id_to_delete; -- Deleting a record from a table that has foreign key reference.
SET FOREIGN_KEY_CHECKS = 1; -- Enabling foreign key checks after running the above query.
Temporarily disable constraints on a table T-SQL, SQL Server
MSSQL
ALTER TABLE TableName NOCHECK CONSTRAINT ALL
ALTER TABLE TableName CHECK CONSTRAINT ALL
ALTER TABLE TableName NOCHECK CONSTRAINT FK_Table_RefTable
ALTER TABLE TableName CHECK CONSTRAINT FK_Table_RefTable
ref
DELETE FROM TableName
DBCC CHECKIDENT ('TableName', RESEED, 0)
MySql
SET FOREIGN_KEY_CHECKS = 0; -- Disable foreign key checking.
TRUNCATE TABLE [YOUR TABLE];
SET FOREIGN_KEY_CHECKS = 1;

SQL Server update primary key that's also a foreign key in two tables

I need to update the primary key for a record but it's also the foreign key in two other tables. And I need the updated primary key to be reflected in the child tables as well.
Here is my query and the error:
begin tran
update question set questionparent = 10000, questionid= 10005 where questionid = 11000;
Error 9/4/2009 10:04:49 AM 0:00:00.000 SQL Server Database Error: The UPDATE statement conflicted with the REFERENCE constraint "FK_GoalRequirement_Question". The conflict occurred in database "numgmttest", table "dbo.GoalRequirement", column 'QuestionID'. 14 0
I don't remember how to go about doing this so that's why I'm here. Any help?
Are your relationships using
ON UPDATE CASCADE
If they are then changing the key in the primary table will update the foreign keys.
e.g.
ALTER TABLE Books
ADD CONSTRAINT fk_author
FOREIGN KEY (AuthorID)
REFERENCES Authors (AuthorID) ON UPDATE CASCADE
You may:
disable enforcing FK constraints temporarily (see here or here)
update your PK
update your FKs
enable back enforcing FK constraints
do it all within a transaction and make sure that if transaction fails, you roll it back properly and still enforce the FK constraints back.
But... why do you need to change a PK? I hope this is an action that is executed rarely (legacy data import or something like that).
If you would like to set the Cascade rule graphically then Set Cascade Rule on SQL Management Studio
Open table in design mode
Click Relationship button from top toolbar
Select the required FK relations (one by one)
Right Side - Expand INSERT or UPDATE Specification
Change the UPDATE Rule to - Cascade
Close and Save, Done!
(Tried on SQL 2008)
As I'm not too confident disabling FK constraints, I prefer too :
Duplicate the row with the old PK with one with the new PK
Update the FKs
Delete the row with the old PK
Advantage : No constraint violated during the process.
Go to foreign Key Relations of each child tables and on Insert and Update specification change delete and update rules to cascade.
create a New row with the same data and a different primary key.
update all the children tables.
remove the row that you repeated its data
And its done.

how to add foreign key constraint, SQL Server

I have a registration table with primary key RegId. I have another table named Users, also contain RegId as Foreign key.
When I delete one RegId from registration, I have to delete RegId from Users. Can anybody help?
Define the foreign key with "ON DELETE CASCADE".
You can do this is in T-SQL or in design view in SSMS
You could to alter the main table with a constraint saying that a Delete On Cascade must be done.
Based on your inputs, something similar to this:
ALTER TABLE dbo.Registration
ADD CONSTRAINT FK_Registration_Users_Cascade
FOREIGN KEY (RegId) REFERENCES dbo.Users(RegId) ON DELETE CASCADE
Also, you can achieve this with the SQL Management Studio selecting your table (in Design mode) and go to Relationships option. There you'll see the "INSERT and UPDATE specifications" button for setting this things.
MSDN Article
Cascading Referential Integrity Constraints

Resources