webForumDet fria alternativet

transaktion

6 svar · 284 visningar · startad av Percy

PercyMedlem sedan mars 2000187 inlägg
#1

hej, har ett problem med att skapa en transaktion.
har förljande kod just nu:

strSQL = "begin tran "
strSQL = strSQL & "INSERT INTO OrderHead (OrderNo, CustomerId, DeliverySurname, Ip) VALUES (" & OrderNo & ", " & CustomerId & ", '" & DeliverySurname & "', '" & Request.ServerVariables("REMOTE_ADDR") & "') "
strSQL = strSQL & "select @@identity "
strSQL = strSQL & "commit tran"

Set ObjRs = Connection.Execute(strSQL)
OrderId = ObjRs(0)

får då felmeddelandet:
ADODB.Recordset error '800a0cc1'

Item cannot be found in the collection corresponding to the requested name or ordinal.

/AddOrder.asp, line 65

rad 65 är:
OrderId = ObjRs(0)

LarsG eller någon annan, vad är det för fel? hur skall det se ut för att få transaktionen att fungera? det jag vill är att få redan på id:t som skapades vid inserten.

tack på förhand

LarsGMedlem sedan dec. 200012 464 inlägg
#2

Det har inget med transaktioner att göra. Med din kod så kommer insert att returnera ett tomt recordset och det är det du får tillbaka vid execute. Resultatet av select-frågan kommer i ett annat recordset som du kan få tag på genom att göra

set objrs = objrs.nextrecordset()

Men om du däremot lägger till

strSQL = "begin tran [b]SET NOCOUNT ON[/b] " 
strSQL = strSQL & "INSERT INTO OrderHead (OrderNo, CustomerId, DeliverySurname, Ip) " &_
"VALUES (" & OrderNo & ", " & CustomerId & ", '" & DeliverySurname & "', '" & _
Request.ServerVariables("REMOTE_ADDR") & "') " 
strSQL = strSQL & "select @@identity " 
strSQL = strSQL & "commit tran"

så kommer insert inte att ge upphov till ett recordset.

PercyMedlem sedan mars 2000187 inlägg
#3

tack LarsG, funkade utmärkt med det sista alt.
nu har jag dock en annan fråga. kan man få in hela nedanstående kod i en transaktion så att ingen annan kan komma och göra inlägg emellan (även om sannolikheten att någon skulle göra det precis mellan två frågor är väldigt liten)

strSQL = "begin tran set nocount on "
strSQL = strSQL & "INSERT INTO OrderHead (OrderNo, CustomerId, DeliverySurname, Ip) VALUES (" & OrderNo & ", " & CustomerId & ", '" & DeliverySurname & "', '" & Request.ServerVariables("REMOTE_ADDR") & "') "
strSQL = strSQL & "select @@identity "
strSQL = strSQL & "commit tran"

Set ObjRs = Connection.Execute(strSQL)
OrderId = ObjRs(0)

strSQL = "SELECT Article.Price, Temporder.ArticleId, Temporder.Amount FROM Article INNER JOIN Temporder ON Temporder.ArticleId = Article.ArticleId WHERE SessionId = " & Request.Cookies("SessionId")
Set rs = Connection.Execute(strSQL)

Do until rs.eof
'lägg till orderrader
strSQL = "INSERT INTO OrderItem (OrderId, ArticleId, Amount, Price) VALUES (" & OrderId & ", " & rs("ArticleId") & ", " & rs("Amount") & ", " & rs("Price") & ")"
Connection.Execute(strSQL)

rs.MoveNext
Loop
rs.Close

'tömmer temporära varukorgen
strSQL = "DELETE FROM Temporder WHERE SessionId = " & Request.Cookies("SessionId")
Connection.Execute(strSQL)

kan man få in den sista select frågan och efterfäljande loop i transaktionen?

LarsGMedlem sedan dec. 200012 464 inlägg
#4

Om du vill sköta allt från ASP så är det nog bättre att använda metoderna begintrans/committrans istället. Din loop där du flyttar data mellan tabeller går att skriva som ett statement med insert ... select

connection.begintrans()

strSQL = "set nocount on "
strSQL = strSQL & "INSERT INTO OrderHead (OrderNo, CustomerId, DeliverySurname, Ip) VALUES (" &_
OrderNo & ", " & CustomerId & ", '" & DeliverySurname & "', '" & Request.ServerVariables("REMOTE_ADDR") & "') "
strSQL = strSQL & "select @@identity "

Set ObjRs = Connection.Execute(strSQL)

strSQL = strSQL & insert into OrderItem SELECT Article.Price, Temporder.ArticleId, Temporder.Amount FROM " &_
" Article INNER JOIN Temporder ON Temporder.ArticleId = Article.ArticleId " &_
" WHERE SessionId = " & Request.Cookies("SessionId")
strSQL = strSQL & " DELETE FROM Temporder WHERE SessionId = " & Request.Cookies("SessionId") & " commit tran"
connection.execute strSQL

connect.committrans()

Du behöver lägga till lite felhantering så att du kan göra rollback om någon operation misslyckas.

Jag skulle nog lägga den här koden i en stored procedure istället.

PercyMedlem sedan mars 2000187 inlägg
#5

tack!
som koden är nu behövs det ingen loop för att lägga in flera poster?:

strSQL = strSQL & insert into OrderItem SELECT Article.Price, Temporder.ArticleId, Temporder.Amount FROM " &_
" Article INNER JOIN Temporder ON Temporder.ArticleId = Article.ArticleId " &_
" WHERE SessionId = " & Request.Cookies("SessionId")

lr den kanske klarar att lägga in fler poster utan att ha en loop?

tanken är att jag ska lägga den i en SP sen. kan dock inte ngt om det ännu...

men hur skulle koden för en SP se ut i så fall?

LarsGMedlem sedan dec. 200012 464 inlägg
#6

Nej, det behövs ingen loop.

Om man skulle göra om det till en stored procedure

create procedure percyFirst(
@orderNo int, 
@customerId int,
@deliverySurname varchar(40),
@sessionId int, 
@ip varchar(40))
as
declare @newId int,@errCode int
set nocount on 
INSERT INTO OrderHead (OrderNo, CustomerId, DeliverySurname, Ip) 
VALUES (@OrderNo,@CustomerId,@DeliverySurname ,@ip)
select @newid = @@identity,@errCode = @@error
if @errCode <> 0 goto panic
 
insert into OrderItem 
SELECT Article.Price, 
    Temporder.ArticleId, 
   Temporder.Amount 
  FROM Article INNER JOIN Temporder 
     ON Temporder.ArticleId = Article.ArticleId 
  WHERE SessionId = @SessionId

select @errCode = @@error
if @errCode <> goto panic
 DELETE FROM Temporder 
  WHERE SessionId = @SessionId
select 0,@newid
return
panic:
select @errCode,0

För att anropa en procedur så använder man kommandot

connect.begintrans()
set rs = connect.execute("execute percyFirst parameter,parameter2,...")
if rs(0) <> 0 then
  connect.rollbacktrans()
else
  connect.committrans()
end if

Tanken är att du får tillbaka ett recordset som innehåller dels en returkod och dels det nya räknarvärdet. Om returkoden <> 0 så får du göra rollback i ditt ASP program.

Mer om stored procedures

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_ca-co_5t9v.asp

PercyMedlem sedan mars 2000187 inlägg
#7

du är en hjälte LarsG :- )
tack, skall se ifall detta fungerar nu...

128 ms totalt · 3 externa anrop · v20260731065814-full.2b84b982
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
126 ms — hämta tråd, inlägg och bilagor (db)