これが難しいのは、デザインに欠陥があるためだと思いますが、それを修正するための十分な情報がありません。あなたがどの患者にベッドを与えようとしているのかわかりません。以下では@PatientIdToGiveBed
、あなたの例のように、すべての「患者」に同じベッドを与えることを指定するためにを使用しました。ベッドが選択されているのと同じ方法で、最初の「入院中」を選択するようにこれを変更する必要がある可能性があります。
トランザクションには、2つのトランザクションが同じベッドを割り当てないようにする分離レベルが必要REPEATABLE READ
です。デフォルトを使用した場合READ COMMITTED
、2つのトランザクションが同じベッドを選択する可能性があります。このようにしREAD LOCK
て、トランザクションが完了するまで、選択したベッドでaが保持されます。
以下のステートメント全体をSSMSに入れて実行し、テストすることができます。
DECLARE @Bed TABLE (
b_ID INT,
Status_Avai_Occ VARCHAR(20)
)
DECLARE @Patient_Record TABLE (
Id INT,
Name VARCHAR(10),
b_ID INT
)
INSERT INTO @Bed VALUES (1, 'Available')
INSERT INTO @Bed VALUES (2, 'Available')
INSERT INTO @Bed VALUES (3, 'Available')
INSERT INTO @Patient_Record VALUES (1, 'Adam', NULL)
INSERT INTO @Patient_Record VALUES (2, 'Ben', NULL)
INSERT INTO @Patient_Record VALUES (3, 'Charles', NULL)
DECLARE @PatientIdToGiveBed INT = 1
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @Available_BID INT
SELECT TOP 1 @Available_BID = b_ID FROM @BED WHERE Status_Avai_Occ = 'Available' ORDER BY b_ID
IF @Available_BID IS NULL
BEGIN
Print 'No Beds Available'
COMMIT
RETURN
END
UPDATE @Patient_Record SET b_ID = @Available_BID WHERE Id = @PatientIdToGiveBed
UPDATE @Bed SET Status_Avai_Occ = 'Occupied' WHERE b_ID = @Available_BID
COMMIT
SELECT * FROM @Patient_Record
SELECT * FROM @Bed