Transferring data when identity column values are different - sql-server-2012

I am in process of restructuring a database and creating a MVC 5 application. There are many tables which are normalized but few remains the same. In the original database table few of the rows were deleted. SO the table data looks like below,
Id Column1
--------------------
1 Some value
2 Some value
4 Some value
8 Some value
9 Some value
Now I am using code first to create new database with some new and some existing database tables. In my entity model I am using the following code to mark a field as primary key and identity,
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
Now the tables created by code first have auto incremented values for ID columns.
Id Column1
--------------------
1 Some value
2 Some value
3 Some value
4 Some value
5 Some value
The number of records for first table are more then 100. ID column for this table is also used as foreign key in another table which has nearly 1000 records. Now problem I am facing is that how to account for the difference in the original table IDs and newly created IDs. If I try to specify the value for ID column explicitly then it gives error that I cannot explicitly specify value for Identity column. I have to write a seed method for both tables. What can be the proper way to handle this scenario?

Related

SQL server, is it possible to selectively over-write a computed column, or an IDENTITY int column

I'm in the process of migrating data to an SQL server database, ideally going foward I want to use the tables in this database to generate unique identities for the data being recorded in them, however the existing data comes with unique identities already.
I'd like to set up a table that looks like this
entry_num (PK)
component (FK)
long_id (Unique) - computed from combining row_num and component
1
THING1
THING1_1
2
THING2
THING2_2
3
THING1
THING2_3
I would like to be able to insert my existing data into the table by including it's existing id in the long_id column, and for future entries calculate the column automatically.
So my original inserted data might look like this:
entry_num (PK)
component (FK)
long_id (Unique) - computed from combining row_num and component
1
THING2
THING2_50
2
THING3
THING3_90
3
THING4
THING4_11
Alternatively could I manually specify the entry_num to match the identities?
I was planning on using
CREATE TABLE table_name (entry_num int IDENTITY...);
to auto increment this column, but is there another way that allows me to manually alter the identities of specific rows without violating the auto incrementing ability?

Database cache in SQL Or correcting autoincrement [duplicate]

This question already has answers here:
How to get rid of gaps in rowid numbering after deleting rows?
(4 answers)
Closed 5 months ago.
I've created 2 rows in an table in SQL (sqlite3 on cmd) and then deleted 1 of them.
CREATE TABLE sample1( name TEXT, id INTEGER PRIMARY KEY AUTOINCREMENT);
INSERT INTO sample1 VALUES ('ROY',1);
INSERT INTO sample1(name) VALUES ('RAJ');
DELETE FROM sample1 WHERE id = 2;
Later when I inserted another row, its id was given 3 by the system instead of 2.
INSERT INTO sample1 VALUES ('AMIE',NULL);
SELECT * FROM sample1;
picture of table
How do I correct it so the next values are given right id's automatically? Or how do I clear the sql database cache to solve it?
The simplest fix to resolve the problem you describe, is to omit AUTOINCREMENT.
The result of your test would then be as you wish.
However, the rowid (which the id column is an alias of, if INTEGER PRIMARY KEY is specified, with or without AUTOINCREMENT), will still be generated and probably be 1 higher than the highest existing id (alias of rowid).
There is a subtle difference between using and not using AUTOINCREMENT.
without AUTOINCREMENT then the generated value of the rowid and therefore it's alias will be the highest existing rowid for the table plus 1 (not absolutely guaranteed though).
with AUTOINCREMENT the generated value will be 1 plus the higher of:-
the highest existing rowid, or
the highest used rowid
the highest, in some circumstances, may have only existed briefly
In your example as 2 had been used then 2 + 1 = 3 even though 2 had been deleted.
Using AUTOINCREMENT is inefficient as to know what the last used value was requires a system table, sqlite_sequence and it being accessed to store the latest id and also to retrieve the id.
The SQLite AUTOINCREMENT documentation, says this:-
The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and disk I/O overhead and should be avoided if not strictly needed. It is usually not needed.
There are other differences, such as with AUTOINCREMENT if the id 9223372036854775807 has been reached, then another insert will result in an SQLITE_FULL error. Whilst without AUTOINCREMENT then an unused id (there would be one as current day storage devices could not hold that number of rows).
The intention of id's (rowid's) is to uniquely identify a row and to be able to access such a row efficiently if accessing it by the id. The intention is not for it to be used as a sequence/order. Using it as a sequence/order number will probably invariably result in unanticipated sequences or inefficient overheads trying to maintain such a sequence/order.
You should always consider that rows are unordered unless specifically ordered by a clause that orders the output, such as an ORDER BY clause.
However, if you take your example a little further, omitting AUTOINCREMENT, will still probably result in the order/sequence issues as if, for example, the row with an id of 1 were deleted instead of 2 then you would end up with id's of 2 and 3.
Perhaps consider the following which shows a) how the limited issue you have posed, is solved without AUTOINCREMENT, and b) that it is not the solution if it is not the highest id that is deleted:-
DROP TABLE IF EXISTS sample1;
CREATE TABLE IF NOT EXISTS sample1( name TEXT, id INTEGER PRIMARY KEY);
INSERT INTO sample1 VALUES ('ROY',1);
INSERT INTO sample1(name) VALUES ('RAJ');
DELETE FROM sample1 WHERE id = 2;
INSERT INTO sample1 VALUES ('AMIE',NULL);
/* Result 1 */
SELECT * FROM sample1;
/* BUT if a lower than the highest id is deleted */
DELETE FROM sample1 WHERE id=1;
INSERT INTO sample1 VALUES ('EMMA',NULL);
/* Result 2 */
SELECT * FROM sample1;
Result 1 (your exact issue resolved)
Result 2 (if not the highest id deleted)

Should I add another table or add a coulmn to exisiting one

I have a table with thousands of entry and want to show if the entity is deleted or not.
I can add a new column "isDeleted" in the existing table and update every entry(thousands) of that entity in the table once it is deleted
OR
have a new table for the deleted entries and join the tables for queries.
I want to know which is faster.
I will be querying from the table and want the information about deleted entities as well as non deleted ones.
Lets say my table has columns:
id
type
prop1
info1
1
A
any
any
2
B
any
any
3
C
any
any
4
A
any
any
5
B
any
any
And i go and delete the type A, now I can have a isDeleted Column in this table only, as such
id
type
prop1
info1
isDeleted
1
A
any
any
true
2
B
any
any
false
3
C
any
any
false
4
A
any
any
true
5
B
any
any
false
or have a new table for deleted types.
with the first method I will have to go and update the isDeleted column for every instance of type A, and there are 1000's of such entries. whereas in the second method i can simply add a new row in the new table.
I want all such unique "types" that have not been deleted from my table. but dont want to remove the deleted types information
I hope this is clearer
The easiest way would be just to add an isDeleted column which is nullable and mark those that you delete as non-null. This would assert backwards compatibility also.
To build on this further, I would instead recommend to make this column into a deleted_at column stored as a nullable timestamp - this way you get the bonus of some extra metadata.
One such benefit of this extra metadata could be for audit trails.
To prevent repeated storage of the same data, add a different table types with columns type and is_deleted. This way, you can avoid inconsistencies, such as when rows 1 and 4 in your proposed example disagree with each other (one is true, another is false).
REFERENCES:
What is the reason to "normalize your databases"?
What is Normalisation (or Normalization)?

Duplicating a row with all the rows below it in the hierarchy tables

I do not know if my request has a name but I think it can be called "duplicating a row with all the rows below it in the hierarchy tables".
I want to create a stored procedure that can duplicate a record and all its childs and grandchilds records.
When I say "Duplicate" I main that all the record values in the columns will be copy to a new record on the same table (the copy should be without Primary key Id column because its automated)
This Stored Procedure needs to get two parameters:
Parameter 1 - Table Name
Parameter 2 - Value of the Primary key Id (of that Table Name) that needs to duplicate.
Instructions of the code:
The value (Parameter 2) will find one record on the table (Parameter 1) and duplicate it (as I said same values for all the columns excluding the primary key of that table.
Then we will need to know all the table names that has a relationship with this primary key (of the parent table)
Then every child table will duplicate the records that have the same Id value (Parameter 2) with the new Id value (of the new parent record).
several things:
In the dream scenario the code knows to go down levels without any limit (children, grandchildren, great-grandchildren ...) ,but I guess it is a very complex code that will contain some recursion code, so even a code containing up to 3-4 levels I will be happily accepted.

Need update eligible data from one table to another

I have 2 tables. One is stage XYZ which contains raw data and the other is main table SKY in which most of the data is loaded as it is from stage.
The stage table is a truncate load table.
I want to check out records between these two which are not same??? In other words , I want to know which all attribute/column value is valid for a change from XYZ to SKY??
Be sure there are many columns in the SKY which is not available in XYZ.
XYZ has around 150 columns in total
And main table has 165( 15 are populated using some Informatica transformation from XYZ values, which i am not worried about)
In my opinion, The table XYZ should have a Auto Increment ID and the table Main will have the reference of that Auto Increment ID value. Once this structure is ready, informatica should always pick new records based on the value in Auto Increment ID column.
The select statement could be-
SELECT * FROM XYZ
WHERE Auto_ID > (SELECT MAX(Auto_ID) FROM Main)
Then you can apply further transformation on selected records for your purpose.