Moving primary key from int to Guid - sql

In my current project, I have to sync multiple client databases to one server database. I had given a try with Microsoft's sync framework and is not useful in my case. Therefor I have to do sync manually. for that I need to change primary key constraints from int to guid in all the tables.
Problem is this primary keys are also referred as foreign key in other tables.
I had referred below,
Moving from ints to GUIDs as primary keys
I am not good at SQL. I understood the logic but actual implementation is very tough for me.
ALTER TABLE MyTable
ADD GuidCol NVARCHAR(50) NOT NULL,
CONSTRAINT AK_GuidCol UNIQUE(GuidCol)
in above code I tried to add a column GuidCol as unique column after googling a lot. But
I don't know How can I fill values in the newly created column?
How can I make this column as PK after assigning value(s)?
How to make sure that this process won't break existing foreign key constraints?

I don't know How can I fill values in the newly created column?
The link you provided gives a solution:
Create a new column for the guid value in the master table. Use the
uniqueidentifier data type, make it not null with a newid()
default so all existing rows will be populated.
So your code should look like this:
alter table myTable add GuidCol uniqueidentifier not null default newid()
How can I make this column as PK after assigning value(s)? How to
make sure that this process won't break existing foreign key
constraints?
The same answer tells you:
Create new uniqueidentifier columns in the child tables.
Run update statements to build the guild relationships using the
exisitng int relationships to reference the entities.
Drop the original int columns.
Use the same uniqueidentifier type as in previuos statement, but instead of providing defalut, run the update statements joining the tables on existing integer id and set in the child's column the corresponding parent value.
Now you have child-parent relationship established but without constraints on them. Drop int columns and create PK and FK on new guid columns

Related

How to solve the ORA-01758 problem without delete data and add primary key

I want Write ALTER TABLE SQL statement to add a column to the table. The column is classified as NUMBER datatype, NOT NULL attribute, and primary key.
But it shows ORA-01758.
ALTER TABLE INSURANCE
ADD (INS_ID NUMBER PRIMARY KEY NOT NULL);
If I select DEFAULT 0, it really solves the problem, but I cannot set up a primary key and INS_ID shows 0, not (null)
Because this table's data is from a excel document, what should I solve it without delete data?
If I must delete data how restore it easily?
Typically you can either:
provide a default value so oracle can fill the column as it creates, satisfying the constraint or
create the column as nullable, fill it with relevant data, then enable the not null restriction/make it the primary key after it has data or
empty the table
1 is not an option for you, because the values will have to be unique if they are to be a primary key. You could consider associating the column with a sequence or making it an identity column though
2 is a likely option for you if an auto generated incrementing number is no good as a PK (for example the key data is already known or calculated)
3 is something you've already said is not an option
Give some thought to the ongoing maintenance requirements - every front end app that writes data into this table will need to be upgraded to understand it has a primary key unless you're using a sequence/identity or similar that provides a unique value for the row. If there will be a lot to update and you dont care to have a PK in a particular form or from some existing value/relationship elsewhere, having an auto number PK can be helpful. If this data needs to relate to existing data that has a key, you need to upgrade front end apps so they can respect the new PK

How can I replace the existing primary key with a new primary key on my table?

I'm working with a legacy SQL Server database which has a core table with a bad primary key.
The key is of type NVARCHAR(50) and contains an application-generated string based on various things in the table. For obvious reasons, I'd like to replace this key with an auto-incrementing (identity) INT column.
This is a huge database and we're upgrading it piece-by-piece. We want to minimize the changes to tables that other components write to. I figured I could change the table without breaking anything by just:
Adding the new Id column to the table and making it nullable
Filling it with unique integers and making it NOT NULL
Dropping the existing primary key while ensuring there's a uniqueness constraint still on that column
Setting the new Id column to be the new primary key and identity
Item 3 is proving very painful. Because this is a core table, there are a lot of other tables with foreign key constraints on it. To drop the existing primary key, it seems I have to delete all these foreign key constraints and create them again afterwards.
Is there an easier way to do this or will I just have to script everything?
Afraid that is the bad news. We just got through a big project of doing the same type of thing, although our head DBA had a few tricks up his sleeve. You might look at something like this to get your scripts generated for the flipping of the switch:
I once did the same thing and basically used the process you describe. Except of course you have to first visit each other table and add new foreign key pointing to the new column in your base table
So the approach I used was
Add a new column with an auto incrementing integer in the base table, ensure it has a unique index on it (to be replaced later by the primary key)
For each foreign key relationship pointing to the base table add a new column in the child table. (note this can result in adding more than one column in the child table if more than one relationship)
For each instance of a key in the child table enter a value into the new foreign key field(s)
Replace your foreign key relationships such that the new column now serves
Make the new column in the base table the primary
Drop the old primary key in the base table and each old foreign key in the
children.
It is doable and not as hard as it might sound at first. The crux is a series of update statements for the children table of the nature
Update child_table
set new_column = (select new_primary from base)
where old_primary = old_foreign

SQLite importing data from a datadump script including primary and foreign keys

I have a SQLite database that makes use of foreign keys, some of which will be autoincremented values. The "core" data the system represents is for example a car. The foreign keys are linking to information about wheels and tyres for example, and I wish to export n cars from one database and import into another.
I want to do this by writing a set of sql statements (i.e a bunch of insert statements) that can be loaded by the importing database, but the key values in the dumped data will not necessarily match up with the existing data (maybe there are duplicates in some of the key values).
What is the best way to deal with this? Is there an easy or recommended way to write the import script so that dependencies on exported key values are removed?
In the example below, a carindex will name a car.
CarPartColours links a single part and with a colour definition. There will be multiple rows in CarPartColours with the same CarID.
I wish to export all the relevant rows from carpartcolours, carindex, parts and colours when the user selects a single row in carindex, and import into another database. The colour definitions in that database may be duplicates (another different issue) or have the same key values as those in the origin db.
CREATE TABLE carindex (
ID integer PRIMARY KEY NOT NULL,
Name varchar(50)
);
CREATE TABLE carpartcolours (
ID integer PRIMARY KEY AUTOINCREMENT NOT NULL,
CarID integer,
PartID integer,
ColourID integer,
/* Foreign keys */
FOREIGN KEY (CarID)
REFERENCES carindex(ID)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
FOREIGN KEY (PartID)
REFERENCES parts(ID)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
FOREIGN KEY (ColourID)
REFERENCES colours(ID)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
CREATE TABLE colours (
ID integer PRIMARY KEY AUTOINCREMENT NOT NULL,
Name varchar(50),
R real,
G real,
B real
);
CREATE TABLE parts (
ID integer PRIMARY KEY AUTOINCREMENT NOT NULL,
Name varchar(50),
Value real,
Manufacturer varchar(50)
);
#Mike I posted a previous answer, and I was on a totally wrong train of thought before, so I'm starting fresh. My apologies.
I would say that you need to make sure you look into database master slave replication, as that's what you're trying to do. You want to replicate the data from the slave to the master. Since you're not going to know which was inserted where when, then you need to look for a collision free key (or try for something collision free). So because you may generate a record in any one database and you may migrate that record to any other database, then you want to generate a UUID style key, and use that in place of a INT AUTOINCREMENT.
This is the only way to do cross database data replication.
Otherwise, you just want to insert into carpartcolours last.
Sorry for the delay in answering your question ...
Try wrapping all your insert statements into transaction:
BEGIN TRANSACTION
// all your inserts go here
END TRANSACTION
I'm not familiar with sqlite per se, but what I have done in the past with similar problems is:
dump out data from origin database, including primary and foreign key values
switch off auto-increment behaviour in target database
import data
switch auto-increment behaviour back on
This may not be possible in sqlite, or may not work because you have pre-existing data with the same primary keys.
In this case, you can import the data from the origin database into temporary tables, and then write scripts to import this into the target database with hand-written SQL, starting at the "furthest" end of the dependency chain. Quite laborious, though.

Replacing PK's in Existing SQL DB Tables

Right now I have a DB where the PK's are int IDENTITY. I recently, in the last year, was tasked with adding these to a Replication Topology. This has worked out quite well with the exception of the IDENTITY fields.
I want to explore my options for changing or replacing them with a uniqeidentifier(GUID).
Is it feasible to insert a NEW PK column?
Would I be better of just increasing it to a big int?
Anything else I should consider?
To elaborate on WHY I want to do do this:
It is my understanding that when Replication encounters an IDENTITY Column it sets aside an Identity Range, say 1-1000(default), for each subscriber to ensure an Unique INT for that column. The more subscribers you have the bigger issue it can become. This leads to the Identity Range Check Constraint errors we keep getting.
Thanks
If you really must remove the INT IDENTITY column, then you'd have to do these steps (more or less):
create the new GUID column in your table and fill it with values
identify all foreign key relationships referencing that table and making a note of those (e.g. store their CREATE scripts on disk or something)
add a new GUID reference field to all the referencing tables
fill those values based on the INT reference field you already have
drop all the FK references to your table
drop the INT IDENTITY PK on your table
make the new GUID column your PK
drop the old INT reference columns from all referencing tables
re-create all foreign key references using the new GUID reference column
I hope that should do the trick.

Alter composite key to include newly added column in sql server 2005

I have a table GB_Assignor_Assignee. I have a primary key which includes this combination(StateCode, CountyID, Doc_Type_Group_Code). Now i have to add a new column Doc_Type_Code. I added it by altering table. I want to include this new column inside this primary key.So my combination will be(StateCode, CountyID, Doc_Type_Group_Code,Doc_Type_Code).
How can i alter this primary key to add new column. I donot want to drop it and then recreate it. Please suggest.
If you want to change the primary key to include a new column, you have to drop and recreate it - there's no other way. You cannot add a column to an existing primary key after it's been created.
The question is: wouldn't you be better off creating a new artificial ID (of type INT) as your PK? You wouldn't have to change it if yet another column comes along, referencing the table will be MUCH easier (JOIN on just a single INT instead of five or six columns)......
You have to drop and recreate your PK.
This involves dropping any foreign keys that reference it. This should be obvious in any case as the foreign keys would also have to change to reflect the new column. (Hopefully not many in the case of composite PKs).
Drop the PK itself.
Create the new PK with the additional column.
Recreate all foreign keys.
The easiest way to do this is to make the change in SQL Server's table designer, and ask it to generate the change script for you.