Multiply users can call store procedure(SP), that will make some changes to mytable in SQL Server. This SP should insert some rows to mytable that has reference to itself through parentid column.
TABLE mytable(
id int identity(1,1) primary key,
name varchar(20) not null,
parentId int not null foreign key references mytable(id)
)
in order to insert row to such table, accordingly to other posts, I have 2 ways:
- Allow null to parentid column by
ALTER TABLE mytable alter column parentid int null;, insert the row, update parentid and than disable null to parentid - Allow IDENTITY by
set identity_insert maytable on, insert dummy row with id=-1 and parentid=-1, insert the correct row with reference to -1, update the parentid to SCOPE_IDENTITY() and in the end set IDENTITY to off
The case:
Assume I take the 2nd way. SP managed to set identity_insert mytable on BUT didn’t yet finished the execution of the rest SP. At this time, there are other INSERT requests(NOT through SP) to the mytable table like INSERT INTO mytable(name,parentid) VALUES('theateist', -1). No id is specified because they assumed that IDENTITY is off and therefore id is auto-incremental.
The Question:
Will this cause errors while inserting because IDENTITY, in this period of time, is ON and not auto-incremental any more and therefore it will require id specification? If yes, it will be better to use the 1st way, isn’t it?
Thank you
identity_insertis a per-connection setting – you won’t affect other connections/statements running against this table.I definitely wouldn’t suggest going the first way, if it could be avoided, since it could impact other users of the table – e.g. some other connection could do a broken insert (
parentid=null) while the column definition allows it, and then your stored proc will break. Also, setting a columnnot nullforces a full table scan to occur, so this won’t work well as the table grows.If you did stick with method 2, you’ve still got an issue with what happens if two connections run this stored proc simultaneously – they’ll both want to insert the
-1row, at different times, and delete it also. You’ll have conflicts.I’m guessing the problem you’re having is inserting the “roots” of the tree(s), since they have no parent, and so you’re attempting to have them self referencing. I’d instead probably make the roots have a null parentid permanently. If there’s some other key column(s), these could be used in a filtered index or indexed view to ensure that only one root exists for each key.
Imagine that we’re building some form of family trees, and ignoring most of the realities of such beasts (such as most families requiring children to have two parents):
This ensures that, within each family (as identified by the surname), exactly one person has a null
ParentID. Hopefully, you can modify this example to fit your model.On SQL Server 2005 and earlier, you have to use an indexed view instead.