foreign key in database - sql-server

i am using linq to sql .dbml ,
May i know what is the best way to add foreign key constraint to the database?
ALTER TABLE Staffs
Add CONSTRAINT fk_Staffs FOREIGN KEY(UserId) REFERENCES Users(Id);
i can write this with no problem. But when my database table increases, i have hard time to maintain the Add Constraint foreign script . Each time when i have multiple update to the database columns, then i will crack my head to update those alter table script.
Could there be a simple process for this? In the .dbml, i can drag and drop the association to add the foreign key, i wonder is there a way that i can export those foreign key into script which like what i wrote above? this is good when i want to do the deployment.
Or must i write the alter script and update it whenever there is changes on tables?
please advice

You only need to do this once per database update that actually changes a FK relationship.
In the context of doing a database refactoring this is usually not a big deal of the whole refactoring.
But if you don't like writing your scripts you can use the table designer i SQL Management Studio.
Right click table -> Design
Right click on the appropritate database column (one of the rows in the designer) -> Relationships
In the dialog, add a new relationship and select related tables and columns in the properties editor.
Done.

This is the right way to do it. You can also do it in the designer as written in another answer here but that way if you have to promote from development to production you must do it all by hand and that is very tedious and can easilly lead to errors.
A compromise can be to use the designer to do the changes and in SQL management studio use the right mouse click and select `Script object...´. Than you do not have to type that much.
You mention a change of table names. Well, that should not happen that often!
If it happens a lot, I advise you to create some naming conventions with your team about how to name your columns (and stick to them) and the amount of work will be limited.

Related

SQL DB Diagram Extract

I am using SQL Server 2011 and need to create a visual representation (diagram). The current structure has no relationships (Foreign Keys) between tables and there are tables without any Primary Keys.
I have tried using SQL Database Diagrams but can't add any relationship between tables without the change happening on the DB itself.
I want to draw relationships without it making any changes.
Are there any free DB Diagram software that I can use in order to achieve this? I have tried DbVisualizer but getting same issues as with the diagram within SQL.
In your case I would do the following:
Generate scripts for your database (schema only) (as #Serg suggested already)
You can do this using SSMS: Right click your database - Tasks - Generate Scripts. Select all tables and then under Advanced, select Schema only at the Types of data to script. Save script and run it in some test environment to generate a schema only copy of your database. (If doing this on the same server, you might need to change the script a little, to give the new database another name)
Dynamically try to "guess" the foreign key relationships
Since you have 500+ tables, you could try to make this script work for
you (of course it would need some testing and tuning to adapt it for your
case) but I used it in the following scenario and it worked.
Hopefully you do have a naming convention. In this script it is assumed that the referenced keys are named the same, but this can be configured.
So, I created the following tables:
CREATE TABLE test (testid int identity(1,1) UNIQUE, description varchar(10))
CREATE TABLE test_item (id int identity(1,1) UNIQUE, testid int)
And the following indexes on their primary keys (normally, you should have them too)
CREATE CLUSTERED INDEX [ix_testid] ON [dbo].[test]([testid] ASC)
CREATE CLUSTERED INDEX [ix_testitemid] ON [dbo].[test_item]([id] ASC)
I did not create a foreign key relationship.
Next I ran the script from the Automatically guessing foreign key constraints article and I managed to get the following result:
Executing all the ALTER statements generated from this script you could get your relationships created in your new database - generate the diagram from this database and you are done! :)
ps. I would suggest you test it out step by step, for example with one table first and then adding others and checking the results.
You can try a working demo of my little test here.
Good luck!

SQL Server: foreign key showing one to one relation instead of one to many

From some mystical reason I starter the database design with the inbuilt Database Diagrams GUI designer (Server Management Studio), actually I only did the first 2 tables (users and product) there rest were done using query commands.
It turns out that at the end there’s something I didn’t expect between:
users (table)
product(table)
I’ve created a foreign key column (“users_id”) in the “product” table pointing to the “users” table (column “users_id”).
Instead of having a one to many relation It seem to be a one to one relation?
Users table is referencing the product table and I don’t want this.
What is the problem?
edit: 4-sep-2014 10:48
I've droped the FK_product_TO_users constraint and created a new one, but still the results are the same.
ALTER TABLE product
DROP CONSTRAINT FK_product_TO_users
GO
ALTER TABLE product
ADD
CONSTRAINT FK_product_TO_users
FOREIGN KEY (users_id)
REFERENCES users (users_id)
edit: 4-sep-2014 12:51
I've rebuilt the database, by using just Queries with no GUI help in the table design. The problem related to FK_product_TO_users was fixed, still I don't know why.
It comes out that after the resolution the same issue is present in two other tables with 2 FK relations.
Besides this, inputting data in those tables seems to work fine.
I'm wondering if this is just a bug of the GUI in the Database Diagram?
This is really interesting one.
You can do one thing: just delete the key FK_product_to_users and rebuild the key.
You do NOT need to delete users_id from product table.

How can we make foreign key among tables after inserting data in those tables?

I have created tables in sql server. And i have also inserted data/rows in that tables.
Now i want to make relationship among them means i want to create foreign key constraints among them, is it possible ?
Whenever i try to create relationship among table a problem is occured. "Saving changes is permitted, The changes you made required table to re-created and dropped"
Please suggest me what should i do to make relationship(foreign key) among them ?
My Child table design is this
this is my parent table:-
please now right what alter query i should write..?
You can try this link
"Error message when you try to save a table in SQL Server 2008: "Saving changes is not permitted"
Another solution is below.
I think the problem is because of a feature when using the GUI. If you have a look at this link it shows you how to work round it. It is a feature which prevents you from dropping and recreating the table which is what SSMS does in the background when you click ok.
The code provided by the previous posted is the best way to do this.
You could do this with a script like this:
alter table ChildTable
add constraint FK_ChildTable_ColumnName foreign key (ColumnName) references ParentTable(PrimaryKeyColumnName)
[Edit] If I read your description correctly the script would be:
alter table emp
add constraint FK_emp_salary foreign key(salary) references testing(roll)
You can only add foreign constraints that aren't violated by existing data. You may also have to add suitable indices first, although this depends on the DBMS. In any case, first make sure your existing data is compatible with the foreign keys you want to introduce. In other words, if you were to create the foreign key first, and then insert the data, you should not produce any foreign key violations.

Automated Filegroup Migration in SQL Server

Recently I've been trying to restructure an old database that was not designed with filegroups (just the default PRIMARY) and, among other things, move a bunch of tables to a new Data filegroup residing on a SAN. I know how to migrate the data:
ALTER TABLE MyTable
DROP CONSTRAINT PK_MyTable WITH (MOVE TO [MyDB_Data])
ALTER TABLE MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY CLUSTERED (MyID)
ON [MyDB_Data]
But damned if this isn't the most tedious work I've ever had to. And it's error-prone. At one point I was halfway (I assume, since there's no progress indicator) through moving a 30 GB table before I realized that I had accidentally included one of the value columns in the PK. So I had to start all over again.
It's even worse when the table has a lot of dependencies. Then I can't just drop the primary key; I have to drop and recreate every foreign key that references it. This leads to hundreds of lines of boilerplate; multiply by 100 tables and it becomes downright asinine. My wrists hurt.
Has anybody come up with a shortcut for this? Are there maybe any tools out there (priced with the notion of one-time-use in mind) that can do it? Perhaps somebody here has had to go through this process before and wrote their own tool/script that they wouldn't mind sharing?
SSMS won't do it, obviously - it can only generate migration scripts for non-clustered indexes (and they have to be indexes, not UNIQUE constraints - on at least a few tables, for better or for worse, the clustered index is not actually the primary key, it's a different UNIQUE constraint).
It's not that the syntax is so complicated that I can't write a code gen for it. At least for the basic drop-and-recreate-the-primary-key part. But add in the overhead of figuring out all the dependencies and generating drop/recreate scripts for all the foreign keys and this starts to feel like it's just over that threshold where it's more work to automate and fully test than it is to just do every table manually as with the example above.
So, the question is: Can this process be automated in any reasonably straightforward way? Are there any alternatives to what I've written above?
Thanks!
The simplest way to do it, IMO, would be to use one of the schema comparison tools (My tool, red gate's SQL Compare, Apex SQL Diff as a couple of examples) to create a script of your schema. Then, edit that script to create all the objects, empty, in the right file groups. Having done that, you can then use the same tools to compare your new DB with correct filegroups, and they will generate the scripts to migrate the data for you. It's worth testing with multiple ones to find which is the most appropriate for you.

SQLSERVER: How to alter an existing table int primary key to become an identity column?

My database has a table with thousands of records. The primary key is an integer. There's a lot of foreign key constraints associated with this column.
I want to change this column to become an identity key. What's the best way to do it? I also need to send this update to our clients installations.
Bonus points for an answer that works in Sql Server 2000.
There's a great feature in SQL Server Management Studio that saved my day.
In SSMS go to Options -> Designers -> Table and Database Designers, check "Auto generate change scripts" and uncheck "Prevent saving changes that require table re-creation".
In object explorer, go to your table and select the column that will get the Identity specification. Right click and select modify. In the Column properties panel, expand the tree "Identity Specification" and change "(Is Identity)" to yes. Now on the upper left size, select the icon "Generate script". Pay attention to the warning messages.
Now you will have a generated script that will drop all your constraints, recreate the table with identity, and recreate the constraints. WOW!
I'll test it and post here my results.
Update: Everything worked fine. I forgot to say in the question that I need the script to reproduce the modification in our clients installations.
In Enterprise Manager, right click the table in table view, select design.
click the left hand side of the column (then, double click identity, in columns underneath, in column properties, turns it on, defaults to auto increment 1
There is no single "ALTER TABLE" DDL for changing an existing column to an identity column. You can only add a new identity column to an existing table.
This can be done in Enterprise Manager but you need to be aware that Sql server is creating a new table and copying you data across in the background. You may have some issues with this. Here is an article that explains this a bit more http://www.mssqltips.com/tip.asp?tip=1397
In your scenario i think you will need a combination of this script and something to disable and reenable your fk's.
If the column is an integer as a part of existing relationships then it is already unique. Therefore you do not have to worry about duplicates! That's one huge hassle avoided already.
You can either issue an ALTER TABLE command to change the column or you can do it with Enterprise Manager.

Resources