HighTechTalks DotNet Forums  

Transactions and getting next identity value on the fly

Dotnet Framework (ADO.net) microsoft.public.dotnet.framework.adonet


Discuss Transactions and getting next identity value on the fly in the Dotnet Framework (ADO.net) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Kursat
 
Posts: n/a

Default Transactions and getting next identity value on the fly - 06-14-2009 , 02:06 PM






Hi,

Consider these 2 ralated tables :

Users
------

UserId : int, identity
UserName : varchar

UserDetails
-------------

UserId : int, foreign key of users table
UserDetail : varchar

I would like to insert into these two tables within the same transaction
like this:

trans.Begin ();
try
{
insertUser(UserName);
insertUserDetail (UserId, UserDetails);
trans.Commit ();
}
catch
{
trans.RollBack();
}

The problem is that insertUserDetails function needs UserId of the newly
created user which is an identity value. I should get the next identity
value before commit. How can I do this with SQL Server and MS Access ?

Thanks in advance

Reply With Quote
  #2  
Old   
sloan
 
Posts: n/a

Default Re: Transactions and getting next identity value on the fly - 06-15-2009 , 03:34 PM






Here is a TSQL workaround.

You're basically asking the question "How do I build relationships outside
of the database?"

Using Guid's is one answer.

........

Here is a different workaround.....but is TSQL, not based on 2 transactions:
My guess is that if you want to keep the two .Net transactions, you'll have
to go GUID based.






SET NOCOUNT ON
GO





DROP Table dbo.Person
GO


DROP Table dbo.Dept
GO


Create Table dbo.Dept
(
DeptID int primary key IDENTITY ( 101 , 1 ) ,
DeptName varchar(12) not null
)
GO



ALTER TABLE dbo.Dept
ADD CONSTRAINT DEPT_DEPTNAME_UNIQUE_CONSTR UNIQUE (DeptName)
GO



Create Table dbo.Person
(

PersonID int primary key IDENTITY ( 1001 , 1 ) ,
DeptID int not null FOREIGN KEY (DeptID) REFERENCES dbo.Dept(DeptID),
SSN varchar(9) not null ,
LastName varchar(12) not null ,
FirstName varchar(12) not null
)

GO




ALTER TABLE dbo.Person
ADD CONSTRAINT PER_SSN_UNIQUE UNIQUE (SSN)
GO




IF OBJECT_ID('tempdb..#TempDept') IS NOT NULL

begin

drop table #TempDept

end



IF OBJECT_ID('tempdb..#TempPerson') IS NOT NULL
begin
drop table #TempPerson
end

IF OBJECT_ID('tempdb..#AuditTablePerson') IS NOT NULL
begin
drop table #AuditTablePerson
end


IF OBJECT_ID('tempdb..#AuditTableDept') IS NOT NULL
begin
drop table #AuditTableDept
end






Create Table #TempPerson
(
PersonID int default 0 , --<<We don't know this one
FakeDeptID int ,
SSN varchar(9) not null ,
LastName varchar(12) not null ,
FirstName varchar(12) not null
)


Create Table #AuditTablePerson
(
SSN varchar(9) not null ,
NewIdentityPersonID int not null
)



Create Table #AuditTableDept
(
DeptName varchar(12) not null ,
NewIdentityDeptID int not null
)



Create Table #TempDept
(
FakeDeptID int not null ,
DeptName varchar(12) not null
)

GO


/*
Notice with the "-111" (and -222) I have a Relationship between the Person
and Dept, but this value
isn't the actual DeptID in the database. We just use this -111 (and -222)
as a holder for the relationship
until the IDENTITIES are actually created.
*/

Insert into #TempDept ( FakeDeptID , DeptName ) values ( -111 ,
'Resources' )
Insert into #TempDept ( FakeDeptID , DeptName ) values ( -222 ,
'Janitorial' )



Insert into #TempPerson ( FakeDeptID , SSN , LastName , FirstName ) values
( -111 , '222222222', 'Person2' , 'Two' )
Insert into #TempPerson ( FakeDeptID , SSN , LastName , FirstName ) values
( -111 , '333333333', 'Person3' , 'Three' )
Insert into #TempPerson ( FakeDeptID , SSN , LastName , FirstName ) values
( -222 , '444444444', 'Person4' , 'Four' )






print '/#TempPerson/'
select * from #TempPerson

print '/#TempDept/'
select * from #TempDept

print '------------<'


Insert Into dbo.Dept (DeptName)
output inserted.DeptName , inserted.DeptID into #AuditTableDept ( DeptName ,
NewIdentityDeptID )
select DeptName from #TempDept td
where not exists ( select null from dbo.Dept innerDept where
innerDept.DeptName = td.DeptName )

print '/#AuditTableDept/'
select * from #AuditTableDept



/*
--Here is where we can get the actual DeptID (created from the IDENTITY) by
using the FakeDeptID relationship we created and
--banking on that the DeptName's are unique
*/

/*
insert into dbo.Person (DeptID , SSN , LastName , FirstName)
output inserted.SSN , inserted.PersonID into #AuditTablePerson ( SSN ,
NewIdentityPersonID )
select ad.NewIdentityDeptID , SSN , LastName , FirstName from #TempPerson tp
join #TempDept td on tp.FakeDeptID = td.FakeDeptID
join #AuditTableDept ad on ad.DeptName = td.DeptName
*/

insert into dbo.Person (DeptID , SSN , LastName , FirstName)
output inserted.SSN , inserted.PersonID into #AuditTablePerson ( SSN ,
NewIdentityPersonID )
select d.DeptID , SSN , LastName , FirstName from #TempPerson tp
join #TempDept td on tp.FakeDeptID = td.FakeDeptID
join dbo.Dept d on d.DeptName = td.DeptName



print 'Hey, I have a list of the new personids as well'
select * from #AuditTablePerson

print 'Update the #TempPerson with the NewIdentityPersonID captured by the
output'

Update #TempPerson Set PersonID = at.NewIdentityPersonID
From #TempPerson tp , #AuditTablePerson at
Where tp.SSN = at.SSN





print '------------<<'
print 'This was stuff left over from a previous example...good for learning,
but you dont need it'
select * from #TempPerson

print '------------<<<'


-----------------
print ''
print '------------------'

print 'Did it work?'
Select p.SSN, d.DeptName from dbo.Person p join dbo.Dept d on p.DeptID =
d.DeptID
select * from dbo.Dept
select * from dbo.Person
print 'Sure Did!!'


IF OBJECT_ID('tempdb..#TempPerson') IS NOT NULL

begin

drop table #TempPerson

end

IF OBJECT_ID('tempdb..#AuditTablePerson') IS NOT NULL

begin

drop table #AuditTablePerson

end

IF OBJECT_ID('tempdb..#TempDept') IS NOT NULL

begin

drop table #TempDept

end



IF OBJECT_ID('tempdb..#AuditTableDept') IS NOT NULL

begin

drop table #AuditTableDept

end





"Kursat" <xx (AT) yy (DOT) com> wrote

Quote:
Hi,

Consider these 2 ralated tables :

Users
------

UserId : int, identity
UserName : varchar

UserDetails
-------------

UserId : int, foreign key of users table
UserDetail : varchar

I would like to insert into these two tables within the same transaction
like this:

trans.Begin ();
try
{
insertUser(UserName);
insertUserDetail (UserId, UserDetails);
trans.Commit ();
}
catch
{
trans.RollBack();
}

The problem is that insertUserDetails function needs UserId of the newly
created user which is an identity value. I should get the next identity
value before commit. How can I do this with SQL Server and MS Access ?

Thanks in advance

Reply With Quote
  #3  
Old   
Dan
 
Posts: n/a

Default Re: Transactions and getting next identity value on the fly - 06-16-2009 , 05:01 PM



Try using Ident_current('TableName')

Dan

"Kursat" <xx (AT) yy (DOT) com> wrote

Quote:
Hi,

Consider these 2 ralated tables :

Users
------

UserId : int, identity
UserName : varchar

UserDetails
-------------

UserId : int, foreign key of users table
UserDetail : varchar

I would like to insert into these two tables within the same transaction
like this:

trans.Begin ();
try
{
insertUser(UserName);
insertUserDetail (UserId, UserDetails);
trans.Commit ();
}
catch
{
trans.RollBack();
}

The problem is that insertUserDetails function needs UserId of the newly
created user which is an identity value. I should get the next identity
value before commit. How can I do this with SQL Server and MS Access ?

Thanks in advance

Reply With Quote
  #4  
Old   
Paul
 
Posts: n/a

Default Re: Transactions and getting next identity value on the fly - 06-19-2009 , 11:03 AM



Use transaction scope,

Call SP on Insert user first return ScopeIdentity. then insert UserDetails
using UserdetailsSP and the returned scopeidentity..

The fact this is a 1:1 releationship suggests to me this could be one table
in any case.


"Kursat" <xx (AT) yy (DOT) com> wrote

Quote:
Hi,

Consider these 2 ralated tables :

Users
------

UserId : int, identity
UserName : varchar

UserDetails
-------------

UserId : int, foreign key of users table
UserDetail : varchar

I would like to insert into these two tables within the same transaction
like this:

trans.Begin ();
try
{
insertUser(UserName);
insertUserDetail (UserId, UserDetails);
trans.Commit ();
}
catch
{
trans.RollBack();
}

The problem is that insertUserDetails function needs UserId of the newly
created user which is an identity value. I should get the next identity
value before commit. How can I do this with SQL Server and MS Access ?

Thanks in advance

Reply With Quote
  #5  
Old   
Kursat
 
Posts: n/a

Default Re: Transactions and getting next identity value on the fly - 06-21-2009 , 04:47 AM



"Paul" <paulriley (AT) novareconsulting (DOT) com> wrote

Quote:
Use transaction scope,

Call SP on Insert user first return ScopeIdentity. then insert UserDetails
using UserdetailsSP and the returned scopeidentity..

The fact this is a 1:1 releationship suggests to me this could be one
table in any case.

The relationship is not 1:1 and I want operations to be transactional. If I
use your technique then what should I do if db connection is down after I
insert into Users table but before inserting UserDetails? How can I solve
data inconsistency?

Reply With Quote
  #6  
Old   
Kursat
 
Posts: n/a

Default Re: Transactions and getting next identity value on the fly - 06-21-2009 , 04:54 AM



"sloan" <sloan (AT) ipass (DOT) net> wrote

Quote:
Here is a TSQL workaround.

You're basically asking the question "How do I build relationships
outside of the database?"

Using Guid's is one answer.

.......

Here is a different workaround.....but is TSQL, not based on 2
transactions:
My guess is that if you want to keep the two .Net transactions, you'll
have to go GUID based.






SET NOCOUNT ON
GO





DROP Table dbo.Person
GO


DROP Table dbo.Dept
GO


Create Table dbo.Dept
(
DeptID int primary key IDENTITY ( 101 , 1 ) ,
DeptName varchar(12) not null
)
GO



ALTER TABLE dbo.Dept
ADD CONSTRAINT DEPT_DEPTNAME_UNIQUE_CONSTR UNIQUE (DeptName)
GO



Create Table dbo.Person
(

PersonID int primary key IDENTITY ( 1001 , 1 ) ,
DeptID int not null FOREIGN KEY (DeptID) REFERENCES dbo.Dept(DeptID),
SSN varchar(9) not null ,
LastName varchar(12) not null ,
FirstName varchar(12) not null
)

GO




ALTER TABLE dbo.Person
ADD CONSTRAINT PER_SSN_UNIQUE UNIQUE (SSN)
GO




IF OBJECT_ID('tempdb..#TempDept') IS NOT NULL

begin

drop table #TempDept

end



IF OBJECT_ID('tempdb..#TempPerson') IS NOT NULL
begin
drop table #TempPerson
end

IF OBJECT_ID('tempdb..#AuditTablePerson') IS NOT NULL
begin
drop table #AuditTablePerson
end


IF OBJECT_ID('tempdb..#AuditTableDept') IS NOT NULL
begin
drop table #AuditTableDept
end






Create Table #TempPerson
(
PersonID int default 0 , --<<We don't know this one
FakeDeptID int ,
SSN varchar(9) not null ,
LastName varchar(12) not null ,
FirstName varchar(12) not null
)


Create Table #AuditTablePerson
(
SSN varchar(9) not null ,
NewIdentityPersonID int not null
)



Create Table #AuditTableDept
(
DeptName varchar(12) not null ,
NewIdentityDeptID int not null
)



Create Table #TempDept
(
FakeDeptID int not null ,
DeptName varchar(12) not null
)

GO


/*
Notice with the "-111" (and -222) I have a Relationship between the Person
and Dept, but this value
isn't the actual DeptID in the database. We just use this -111 (and -222)
as a holder for the relationship
until the IDENTITIES are actually created.
*/

Insert into #TempDept ( FakeDeptID , DeptName ) values ( -111 ,
'Resources' )
Insert into #TempDept ( FakeDeptID , DeptName ) values ( -222 ,
'Janitorial' )



Insert into #TempPerson ( FakeDeptID , SSN , LastName , FirstName )
values ( -111 , '222222222', 'Person2' , 'Two' )
Insert into #TempPerson ( FakeDeptID , SSN , LastName , FirstName )
values ( -111 , '333333333', 'Person3' , 'Three' )
Insert into #TempPerson ( FakeDeptID , SSN , LastName , FirstName )
values ( -222 , '444444444', 'Person4' , 'Four' )






print '/#TempPerson/'
select * from #TempPerson

print '/#TempDept/'
select * from #TempDept

print '------------<'


Insert Into dbo.Dept (DeptName)
output inserted.DeptName , inserted.DeptID into #AuditTableDept ( DeptName
, NewIdentityDeptID )
select DeptName from #TempDept td
where not exists ( select null from dbo.Dept innerDept where
innerDept.DeptName = td.DeptName )

print '/#AuditTableDept/'
select * from #AuditTableDept



/*
--Here is where we can get the actual DeptID (created from the IDENTITY)
by using the FakeDeptID relationship we created and
--banking on that the DeptName's are unique
*/

/*
insert into dbo.Person (DeptID , SSN , LastName , FirstName)
output inserted.SSN , inserted.PersonID into #AuditTablePerson ( SSN ,
NewIdentityPersonID )
select ad.NewIdentityDeptID , SSN , LastName , FirstName from #TempPerson
tp
join #TempDept td on tp.FakeDeptID = td.FakeDeptID
join #AuditTableDept ad on ad.DeptName = td.DeptName
*/

insert into dbo.Person (DeptID , SSN , LastName , FirstName)
output inserted.SSN , inserted.PersonID into #AuditTablePerson ( SSN ,
NewIdentityPersonID )
select d.DeptID , SSN , LastName , FirstName from #TempPerson tp
join #TempDept td on tp.FakeDeptID = td.FakeDeptID
join dbo.Dept d on d.DeptName = td.DeptName



print 'Hey, I have a list of the new personids as well'
select * from #AuditTablePerson

print 'Update the #TempPerson with the NewIdentityPersonID captured by the
output'

Update #TempPerson Set PersonID = at.NewIdentityPersonID
From #TempPerson tp , #AuditTablePerson at
Where tp.SSN = at.SSN





print '------------<<'
print 'This was stuff left over from a previous example...good for
learning, but you dont need it'
select * from #TempPerson

print '------------<<<'


-----------------
print ''
print '------------------'

print 'Did it work?'
Select p.SSN, d.DeptName from dbo.Person p join dbo.Dept d on p.DeptID =
d.DeptID
select * from dbo.Dept
select * from dbo.Person
print 'Sure Did!!'


IF OBJECT_ID('tempdb..#TempPerson') IS NOT NULL

begin

drop table #TempPerson

end

IF OBJECT_ID('tempdb..#AuditTablePerson') IS NOT NULL

begin

drop table #AuditTablePerson

end

IF OBJECT_ID('tempdb..#TempDept') IS NOT NULL

begin

drop table #TempDept

end



IF OBJECT_ID('tempdb..#AuditTableDept') IS NOT NULL

begin

drop table #AuditTableDept

end




Two transactions ? I have never mention two transactions. What I try to do
is so simple, I want to do what I write in the below pseudocode in
transactional manner (i.e. committed or rolledback together):

BeginTrans;
try
{
insertIntoToTableA
insertIntoTableBWith
CommitTrans;
}
catch
{
RollbackTrans
}

The problem is how should I get identity column's value from tableA.

Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.