У меня есть хранимая процедура, которая выполняет MERGE
заявление .
Кажется, что при выполнении слияния по умолчанию блокируется вся таблица.
Я вызываю эту хранимую процедуру внутри транзакции, где я также делаю некоторые другие вещи, и я хотел бы, чтобы она блокировала только затронутые строки.
Я попробовал подсказку, MERGE INTO myTable WITH (READPAST)
и она, казалось, стала меньше. Но в документе MS было предупреждение о том, что он может вставлять дубликаты ключей, минуя даже первичный ключ.
Вот моя схема таблицы:
CREATE TABLE StudentDetails
(
StudentID INTEGER PRIMARY KEY,
StudentName VARCHAR(15)
)
GO
INSERT INTO StudentDetails
VALUES(1,'WANG')
INSERT INTO StudentDetails
VALUES(2,'JOHNSON')
GO
CREATE TABLE StudentTotalMarks
(
Id INT IDENTITY PRIMARY KEY,
StudentID INTEGER REFERENCES StudentDetails,
StudentMarks INTEGER
)
GO
INSERT INTO StudentTotalMarks
VALUES(1,230)
INSERT INTO StudentTotalMarks
VALUES(2,255)
GO
Вот моя хранимая процедура:
CREATE PROCEDURE MergeTest
@StudentId int,
@Mark int
AS
WITH Params
AS
(
SELECT @StudentId as StudentId,
@Mark as Mark
)
MERGE StudentTotalMarks AS stm
USING Params p
ON stm.StudentID = p.StudentId
WHEN MATCHED AND stm.StudentMarks > 250 THEN DELETE
WHEN MATCHED THEN UPDATE SET stm.StudentMarks = p.Mark
WHEN NOT MATCHED THEN
INSERT(StudentID,StudentMarks)
VALUES(p.StudentId, p.Mark);
GO
Вот как я наблюдаю за блокировкой:
begin tran
EXEC MergeTest 1, 1
А потом в другой сессии:
EXEC MergeTest 2, 2
Второй сеанс ожидает завершения первого, прежде чем продолжить.
WITH (READPAST)
инструктирует SQL Server просто пропускать строки, заблокированные другими сеансами. Вы уверены, что хотите это сделать? Кроме того, сколько строк в этой таблице вы изменяете? Покажите нам схему таблицы (включая индексы) иMERGE
оператор, который вы выполняете.