I'm building an ASP.Net/MVC application using SQL 2008 Developer edition and a DB in Sql2005 compatibility mode. Using Entity Framework as DAL.
My problem is that I have a table where I'm using the integer identity column in a like an Invoice Number, that is, it always has to be unique and never reused. So using the GUID column type won't work without a substantial effort.
What I'm seeing is that the DB is filling in the gaps in the identity column. This will cause me long term problems. Is there a setting to disable this "filling in"
That sounds like something outside SQL server; SQL server does not "go back" and re-use gaps in identities unless the table's been reseeded, but even then it will blindly increment one-by-one and probably return a lot of duplicate key errors as it hits rows with existing values.
Are you sure the column is an identity? Is there anything else that might be re-assigning keys and/or turning on identity insert when creating rows?
SQL Server does not fill in the gaps of an identity field by default it will just keep going up in numbers as you insert rows.
It is possible to reset the identity back to 1 and therefore you may then see what you are describing.
Can I suggest you post some code / db structure that shows your problem and search for any code you may have that my perform an identity reseed.
Unless I am not understanding your issue correctly. If you create a primary key on your identity column, or a unique constraint, you can avoid the issue of duplicate values.
For example:
create table TableName
(
InvoiceID int identity(1,1) not null primary key
)
Related
I just noticed that if I have an identity column in a table, when I insert new rows SQL Server 2008 is automatically filling up the sequence if there are discontinuity. I mean, if in my identity column I have 1,2,5,6 if I insert other two rows in the table the system puts automatically 3,7 in the identity column.
Do you know how to control this behavior?
THANKS
That is the defined and documented SQL Server behavior, and there's really not much you can do about changing it. What did you want to change about it??
IDENTITY columns will guarantee unique, ever-increasing ID's (as long as you don't mess around with them) - they don't guarantee anything else.
SQL Server will not go through the trouble of spotting "gaps" in your sequence and filling them up. I don't think that would be a good idea, anyway - what if you did have a record with ID=3, and then deleted it? Do you really want a next record to suddenly "recycle" that ID?? Not a good idea, in my opinion.
So, my issue is that I am trying to make something that will easily load in Excel datasheets into a SQL database, but before this I have to try and make the identity specification cooperate with me.
The issue begins when I assign the primary key with identity specification being true, as then I get the error message "Cannot insert explicit value for identity column in table 'Priskod' when IDENTITY_INSERT is set to OFF."
However when I set that identity specification is false, then I get the error message "Violation of PRIMARY KEY constraint 'PK_dbo.Priskod'. Cannot insert duplicate key in object 'dbo.Priskod'. The duplicate key value is (0). The statement has been terminated."
Does anyone have any suggestions about how I can fix this?
It sound like you have an Excel spreadsheet that holds data that you want to import into a SQL Server table.
The issue is that you are trying to load it directly in to the source table and to enable this, you are disabling the IDENTITY column. This should ring alarm bells really, as SQL is right when it prevents you from inserting duplicate keys.
There are 2 options here:
The key values in Excel are true identity values that are unique, so you will only INSERT records they don't exist in the target table. This would probably be best achieved by importing to a staging/temp table first and the inserting where the ID doesn't exist. You may also want to perform an UPDATE on rows where the ID does exist.
The key values in Excel are NOT true identity values.
Either way, I think you should add a new column to your target table like: ExternalId, which can be duplicated if required or checked against to prevent duplicates. With both approaches, you should leave the IDENTITY insert as it is.
Got the system to work now.
I had to enter the information straight into the database instead of actually trying to upload the information into the database itself. So thanks everyone for your help and support. You are all super.
I have a database server.
The application logic is that it will query to see if a particular row exist, if not, it will insert a new row. The query is done in Java and container managed transactions.
So with 2 application server running the same code, is it possible for both servers to check the row don't exist, and both insert the row. (the insert will be successful due to another unique auto-number primary key column)
how do we ensure there is only one and only one unique row for that data ?
sknaht
the insert will be successful due to another unique auto-number primary key column
Most DBMSes offer a way to create a "unique key" or "unique index" that enforces uniqueness of a given column (or set of columns) even if it's not the primary key. The second insert would then fail, just as if it had violated a primary-key constraint.
You haven't indicated what DBMS you're using, but most (all?) of the common ones have this feature; for example, PostgreSQL, MySQL, SQL Server, and Oracle all do.
I have not been able to find any appropriate solution for my problem, so here's my question for you:
In Entity Framework (5.0), how can I setup an ID-column (PK) to be autocremented when no identity column is defined in the actual database (SQL Server 2005)?
I have seen the StoreGeneratedPattern, but not sure how this would work without identity in the db. The manual approach would be to manually populate the POCO with MAX(id)+1, but that feels like a hack and I'm worried that it will introduce problems in a multi-threaded environment where multiple requests may insert records to my table at the "same" time.
Note that I do not have the possibility to alter the table schema in the database.
What's the best way to solve this?
If one instance of your application is the only thing inserting rows into this table, then the MAX(Id) + 1 hack is probably good enough. Otherwise, you'll need to alter the database schema to generate these values on insert -- either by using IDENTITY or by re-inventing the wheel using triggers, sprocs, etc.
Whatever your solution, it should guarantee that a duplicate key will never be generated -- even if a transaction happens to rollback one or more inserts.
If nothing else inserts into the table, you should be able to alter Id to an identity column without breaking compatibility.
FYI: Entity Framework's StoreGeneratedPattern (or DatabaseGeneratedOption) only specifies how values are handled on insert and update. Using Identity tells EF that the value is expected to be generated by the database on insert. Computed means it's generated on both insert and update.
I'm using visual studio 2010 an working on asp.net mvc3 project and sql server 2008. I have a table that the primary key of this table is int data type. I set Identity Specificatin "yes", Is Identity "yes", Identity Increment and Identity Seed "1". everything is OK when table is empty and data can be saved easily, But when I close visual studio, open it again and want to save data a break occured that shows the value of primary key is "1". (I deleted the data of database once, after this deletion the primary key of first row is 5 and other rows 6,7,...). What's the solution for this problem? your answer will be so helpfull. Thanks
There is no solution for *automatic gap removal": identity columns always have gaps for good reasons. For example, the deleted row is probably in some history or audit table and you don't wan to reuse it.
However, you can reset the column by using DBCC CHECKIDENT
Note the gotchas here: SQL server identity column values start at 0 instead of 1
Using Sequence type for the Primary Key may help...