I set up a normal binding source with a datagridview to a table. I also set the ID to identity so that I wouldn't have to worry about it. But whenever I call .UpdateAll() on the BindingSource I get the SQL Exception
"Cannot insert explicit value for identity column in table 'Teachers'
when IDENTITY_INSERT is set to OFF."
Now how do I tell the binding Source NOT to push the empty ID column to the table? I know this seems like an issue that was already discussed a hundred times before, but I'm new to this and it's driving me crazy.
Depending on what you want to achieve there is a couple of approach. If you want your identity column to contain non-unique values (which isn't very good idea, but the decision is yours to make) then you can simply disable the identity column in the database:
SET IDENTITY_INSERT Teachers ON;
To revert it run the following:
SET IDENTITY_INSERT Teachers OFF;
But probably, what makes more sense is to make your identity column autoincrement. So when designing your Teachers table the ID column should have this form:
[ID] [int] IDENTITY(1,1) NOT NULL
Or, if you are using SQL Server Management Studio:
Go to your table. Right click it and select Design.
Select the ID column.
In column properties tab find "Identity Specification".
Set "Is Identity" to "Yes", "Identity Increment" to "1", "Identity Seed" to "1".
That should make your ID column to increase automatically hence avoiding empty value when updating the data from the DataGridView.
Related
I have a table Users with 3 columns Id, Name, Address.
I am using usersTableAdapter.Insert() for adding a new record, but it requires all 3 parameters including Id which is Identity column and auto-incremented and cannot be added manually.
Here is the code:
this.usersTableAdapter.Insert("Haroon", "Pakistan");
This is not working.
Is there any way to use the above command without providing an Id value?
Yes; you've set your tableadapter up incorrectly..
Examine this screenshot of a tableadapter conencted to a sql server table that has an autoincrement ID column. You can see the table design from SSMS in the to right (blue border). You can see highlighted that the table adapter was created with select * from autoinctable and the wizard has ONLY chosen to reference the Text column for INSERT (also highlighted)
In code, the Insert command only asks for the Text column:
This TA was created with "refresh the dataset" turned on; you can see in the commands (like insert) that the database calculated value is retrieved (select ... scope_identity)
I want to get new id(Identity) before insert it. so, use this code:
select SCOPE_IDENTITY() AS NewId from tblName
but is get this:
1- Null
2- Null
COMPUTED COLUMN VERSION
You'll have to do this on the sql server to add the column.
alter table TableName add Code as (name + cast(id as varchar(200)))
Now your result set will always have Code as the name + id value, nice because this column will remain updated with that expression even if the field are changed (such as name).
Entity Framework Option (Less ideal)
You mentioned you are using Entity Framework. You need to concatenate the ID on a field within the same record during insert. There is no capacity in SQL (outside of Triggers) or Entity Framework to do what you are wanting in one step.
You need to do something like this:
var obj = new Thing{ field1= "some value", field2 = ""};
context.ThingTable.Add(obj);
context.SaveChanges();
obj.field2 = "bb" + obj.id; //after the first SaveChanges is when your id field would be populated
context.SaveChanges();
ORIGINAL Answer:
If you really must show this value to the user then the safe way to do it would be something like this:
begin tran
insert into test(test) values('this is something')
declare #pk int = scope_identity()
print #pk
You can now return the value in #pk and let the user determine if its acceptable. If it is then issue a COMMIT else issue the ROLLBACK command.
This however is not a very good design and I would think a misuse of the how identity values are generated. Also you should know if you perform a rollback, the ID that would of been used is lost and wont' be used again.
This is too verbose for a comment.
Consider how flawed this concept really is. The identity property is a running tally of the number of attempted inserts. You are wanting to return to the user the identity of a row that does not yet exist. Consider what would happen if you have values in the insert that cause it too fail. You already told the user what the identity would be but the insert failed so that identity has already been consumed. You should report to the user the value when the row actually exists, which is after the insert.
I can't understand why you want to show that identity to user before insert, I believe (as #SeanLange said) that is not custom and not useful, but if you insist I think you can do some infirm ways. One of them is
1) Insert new row then get ID with SCOPE_IDENTITY() and show to user
2) Then if you want to cancel operation delete the row and reset
identity (if necessary) with DBCC CHECKIDENT('[Table Name]', RESEED,
[Identity Seed]) method
Other way is not using the Identity column and manage id column by yourself and it must be clear this approach can't be work in concurrency scenarios.
I think perhaps you're confusing the SQL identity with a ORACLE sequence.
They work completely different.
With the ORACLE sequence you'll get the sequence before you insert the record.
With a SQL Identity, the last identity generated AFTER the insert in available via the SCOPE_IDENTITY() function.
If you really need to show the ID to the user before the insert, your best bet is to keep a counter in a separate table, and read the current value, and increment that by one. As long as "gaps" in the numbers aren't a problem.
I'm trying store data in a local database(SQL CE). I've set a property of RowObject like this:
[Column(IsPrimaryKey=true,CanBeNull=false,IsDbGenerated=true,AutoSync=AutoSync.OnInsert,DbType="int NOT NULL IDENTITY")]
public int key
{ get; set; }
and the primary key is automatically auto-incremented when I insert a new record. But if I remove one or more record and then I insert a new record, its primary key value corresponds at the primary key value of the last inserted record plus one, although that record was deleted.
I know it is not possible to update all primary keys. But, is it possible to control the increment of the primary key?and avoid the continuous increment of the primary key?
ok, thank you for your answer. I ask because I'm worried that PK reaches its maximum value. Maybe this isn't a really problem for my project, but I want understand how handle it, in case it happens. And in case, if it is possible, how can I understand and handle if the database is completely full.
that's violating auto increment.
I sometimes due to need disable auto incrementation of a column to add a row which is deleted on the old place and then enable it again.
If you insist on doing so, you can add 2 triggers, in the delete trigger disable column's auto increment behaviour, then enable it again on another trigger which is after insert trigger.
So on delete disable it, on next insert add it with the max(ID)+1 and after insert enable it again.
For example:
-------------Person Table--------------
ID[Auto-Increment]----Name----Age
10000-------------------Jack-------21
10001-------------------Shawn----19
10002-------------------Albert-----33
Delete from Person where ID = 10002;
set identity_insert AAA ON
now the next ID will be 10003 but you want 10002
DECLARE #ID int;
select #ID = max(ID)+1 from Person
Insert into Person(ID,Name,Age) values(#ID,'Mahdi',23)
set identity_insert AAA OFF --Auto Increments from now on
you should just check to see if you should insert your record with/without ID, I put that burden on your shoulder.
GOOD LUCK.
I'm trying to insert order details into my DB, and it keeps saying:
Cannot insert explicit value for identity column in table 'Orders' when IDENTITY_INSERT is set to OFF.
All I am trying to do is simply insert the users UserId into the UserId column, by using WebSecurity.CurrentUserId - Why is this not working?
I have:
dbase.Execute("INSERT INTO Orders
(UserId, OrderId, Status)
VALUES
(#0, #1, #2)",
WebSecurity.CurrentUserId,
Session["OSFOID"],
"Confirmed");`
So, as you can see, it's pretty simple. But, why won't it work?
My table definition is:
Unless you enable the ability to do identity-insert (by setting identity-insert on for that table), you are NOT ALLOWED to touch that column - the database owns it.
Either enable identity insert briefly, or: don't try to insert the UserId (let the DB create a new id).
As per books online, SET IDENTITY_INSERT:
SET IDENTITY_INSERT Orders ON
INSERT INTO Orders (UserId, OrderId, Status) VALUES (#0, #1, #2)
SET IDENTITY_INSERT Orders OFF
More likely, though: if this is the Orders table, should the identity not be on OrderId ? You'd still have the same problem since you are trying to control the OrderId, of course.
Generally you would not want to insert an integer into a primary key column. You would usually set the column's "Identity" flag to true only where you wanted to have SQL Server set an auto-incrementing integer into this column on insert.
As with Marc Gravell's answer, you can enable identity insert using
SET IDENTITY_INSERT [ database. [ owner. ] ] { table } { ON | OFF }
But doing this in regular application code is really unhealthy -- you'll end up with concurrency issues and quite likely duplicate identities. Better, don't insert the Order's ID -- let the DB do it for you automatically, and then simply query for the new ID using ##IDENTITY (or better, SCOPE_IDENTITY()).
If for some reason you definitely need to store the user's session id, make this a separate column on the order table, or better still, on a separate User table, with the UserId being a foreign key.
You do not want the UserID to be an Identity, and I also do not think you want the UserID to be the primary key either. More than likely, you want the OrderID to be the primary key, or at best shared primary key with the userid and orderid.
In your table's definition set Is Identity? as False, with out setting that you cant insert a value manually to the UserID
You have set IS Identity to YES that's why now you cant insert value for this column DB will automatically insert it by incrementing values..
And the thing i am seeing you set UserId as the primary key of the table which is wrong Order OoderID should be the primary key of the column.
Set UserID IsIdentify to false
and OrderID IsEdentitfy to yes and made it primary key column.
Interestingly I found that when I created a table using a "Select.....Into [new table] from [tables containing data]" I subsequently could not Insert new records, getting the Insert_Identity set to off message.
I got around this by deleting the table then using a Create Table script to rebuild it and now have no problems inserting as many new IDs as needed
I'm Developing a small windows application in C#.net in Visual Studio 2010 with framework 3.5. I use LinqToSql for database manipulation.
table name: cprofile
Fields of the table are:
custid int (primary key),
custname varchar(50),
address nvarchar(MAX),
mobileno nchar(10)
So i have changed the 'Is identity' property of the 'cust id' to 'yes'. It automatically changes other 2 sub properties.
Identity Increment = 1
Identity Seed = 1,
After these changes have been made in the table, it throws error when I try to save a new record.
"Cannot insert explicit value for identity column in table 'cprofile'
when IDENTITY_INSERT is set to OFF."
Not too familiar with L2S, but I'd say Daniel is correct: update your model (usually on a context menu somewhere) from the DB. That should prevent it from attempting to insert a value into your auto-incrementing ID column.
I believe there may be a way to have it set IDENTIY_INSERT ON, but I highly recommend against it.
If your table should not be in charge of setting the CustomerId (say, the business has some method of making that determination (especially in a non-linear way), leave your Customer Id column as the PK, but remove the Identity specificaiton from the column.
If you're trying to use the same insert statement you were using before, you can no longer do that. I'm not sure how it's done in the C# side of it, but in SQL, you'd have to run statements to turn identity_insert on, then run your statement. Because you changed the column to identity, the table makes sure the next entry is always 1 number higher than the previous. Because of this, you can't simply insert values into it. If you want the table to create the identity value for you, simply remove it. If my explanation doesn't help, hopefully this will.
Table Definition (Table1)
Col1 Identity
Col2 varchar(50)
Col3 bool
Insert statement before identity
INSERT INTO Table1 VALUES (1, 'Test', TRUE)
Insert statement after identity
INSERT INTO Table1 VALUES ('Test', TRUE)
When identity is on, you cannot specify the value without turning on identity_edit. I'll see if I can find how to do that in Linq.
EDIT: I also like what Daniel said. Didn't think about that.