Jeg må skrive en T-SQL-lagret prosedyre som oppdaterer en rad i en tabell. Hvis raden ikke finnes, setter den inn. Alle disse trinnene pakkes inn i en transaksjon.
Dette er for et bookingsystem, så den må være atomisk og pålitelig. Den må returnere true hvis transaksjonen er gjennomført og flyreisen er booket.
Jeg er ny i T-SQL, og er ikke sikker på hvordan jeg skal bruke @@rowcount
. Dette er hva jeg har skrevet til nå. Er jeg på rett vei? Det er sikkert et enkelt problem for deg.
-- BEGIN TRANSACTION (HOW TO DO?)
UPDATE Bookings
SET TicketsBooked = TicketsBooked + @TicketsToBook
WHERE FlightId = @Id AND TicketsMax < (TicketsBooked + @TicketsToBook)
-- Here I need to insert only if the row doesn't exists.
-- If the row exists but the condition TicketsMax is violated, I must not insert
-- the row and return FALSE
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO Bookings ... (omitted)
END
-- END TRANSACTION (HOW TO DO?)
-- Return TRUE (How to do?)
Jeg antar at det er én rad for hver flyvning? I så fall, ja:
IF EXISTS (SELECT * FROM Bookings WHERE FLightID = @Id)
BEGIN
--UPDATE HERE
END
ELSE
BEGIN
-- INSERT HERE
END
Jeg antar det jeg sa, ettersom måten du gjør det på kan overbooke en flyvning, da den setter inn en ny rad når det er maks 10 billetter og du bestiller 20.
Dette er noe jeg nylig måtte gjøre:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[cjso_UpdateCustomerLogin]
(
@CustomerID AS INT,
@UserName AS VARCHAR(25),
@Password AS BINARY(16)
)
AS
BEGIN
IF ISNULL((SELECT CustomerID FROM tblOnline_CustomerAccount WHERE CustomerID = @CustomerID), 0) = 0
BEGIN
INSERT INTO [tblOnline_CustomerAccount] (
[CustomerID],
[UserName],
[Password],
[LastLogin]
) VALUES (
/* CustomerID - int */ @CustomerID,
/* UserName - varchar(25) */ @UserName,
/* Password - binary(16) */ @Password,
/* LastLogin - datetime */ NULL )
END
ELSE
BEGIN
UPDATE [tblOnline_CustomerAccount]
SET UserName = @UserName,
Password = @Password
WHERE CustomerID = @CustomerID
END
END