2014-11-21 68 views
0

SQL对此问题的基本性质表示歉意,但它来自SQL noob。存储过程的正确锁定

我在一些在线研究后创建了以下存储过程。该过程的目的是维持计数(VisitCount),因此需要适当的锁定以保持完整性。据我所知MERGE给出了这种情况下正确的锁定水平,但我会很感激,如果有人可以建议这是否正确与否。

谢谢。

ALTER PROCEDURE dbo.Popularity_Update 
    @TermID int 
AS 
    SET NOCOUNT ON 

    DECLARE @Now date = SYSDATETIME() 

    BEGIN TRY 
     MERGE Popularity AS t 
     USING (SELECT @TermID AS TermID, @Now AS VisitDate) AS s ON t.TermID = s.TermID 
                   AND t.VisitDate = s.VisitDate 

     WHEN MATCHED THEN 
      UPDATE 
       SET VisitCount += 1 

     WHEN NOT MATCHED BY TARGET THEN 
      INSERT (TermID, VisitDate, VisitCount) 
      VALUES (s.TermID, s.VisitDate, 1); 

    END TRY 
    BEGIN CATCH 
    END CATCH 
+0

并不完全知道你是问什么,但你的查询是极不可能做你想要什么。除非VisitDate中的值恰好与当前时间匹配,否则您不会获得匹配。 SYSDATETIME精确到第二个7位小数。 – 2014-11-21 14:33:35

+0

哦,我没有看到你把它宣布为日期。 – 2014-11-21 14:34:46

+0

Shoudnt你有一个触发器,而不是调用一个过程 – Mihai 2014-11-21 14:36:57

回答

0

这个怎么样....

ALTER PROCEDURE dbo.Popularity_Update 
    @TermID int 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @Now date = SYSDATETIME() 

    BEGIN TRY 

     UPDATE Popularity 
     SET VisitCount = COALESCE(VisitCount, 0) + 1 
     WHERE TermID = @TermID 
     AND VisitDate = @Now 

     IF (@@ROWCOUNT = 0) 
     BEGIN 
     INSERT INTO Popularity (TermID, VisitDate, VisitCount) 
     VALUES (@TermID, @Now, 1) 
     END 

    END TRY 
    BEGIN CATCH 

    END CATCH 
END 
+0

这和OP差不多。那么这是我们在MERGE之前不得不这样做的方式。 – 2014-11-21 14:45:00

+0

这当然不是,MERGE声明是一个坏消息,应该远离它。无论如何,我只用两个变量就没有使用Merge语句。 – 2014-11-21 14:47:02

+0

@ M.Ali - 正如我以前所说,我不是SQL专家,所以将不得不寻求其他SQL大师的指导 – dotnetnoob 2014-11-21 14:47:40