返回数据和更新行没有多个查找?

时间:2011-01-29 04:34:31

标签: sql-server

我有一个基于文章标题查找文章的存储过程。但我还需要在同一个表中增加一个列,该列计算查看文章的次数。

尽量提高效率,我认为有两种方法可以解决这个问题:

  1. 执行一次SELECT以获取目标行上的PK。然后使用该PK增加视图的数量,最后使用PK返回另一个SELECT以返回文章数据。

  2. 执行一个SELECT将文章数据返回给我的应用程序,然后使用返回的PK再次往返数据库以增加视图数量。

  3. 我知道#1会很快,但它是三次查找。 #2需要两次往返数据库。有没有办法优化这项任务?

    编辑根据反馈,我想出了以下内容。感谢您的任何评论或建设性的批评。

    DECLARE @Slug VARCHAR(250) -- Stored procedure argument
    
    -- declare @UpdatedArticle table variable 
    DECLARE @UpdatedArticle TABLE
    (
        ArtID INT,
        ArtUserID UNIQUEIDENTIFIER,
        ArtSubcategoryID INT,
        ArtTitle VARCHAR(250),
        ArtHtml VARCHAR(MAX),
        ArtDescription VARCHAR(350),
        ArtKeywords VARCHAR(250),
        ArtLicenseID VARCHAR(10),
        ArtViews BIGINT,
        ArtCreated DATETIME2(7),
        ArtUpdated DATETIME2(7)
    );
    
    UPDATE Article
        SET ArtViews = ArtViews + 1
    OUTPUT
        INSERTED.ArtID,
        INSERTED.ArtUserID,
        inserted.ArtSubcategoryID,
        INSERTED.ArtTitle,
        INSERTED.ArtHtml,
        INSERTED.ArtDescription,
        INSERTED.ArtKeywords,
        INSERTED.ArtLicenseID,
        INSERTED.ArtViews,
        INSERTED.ArtUpdated,
        INSERTED.ArtCreated
    INTO @UpdatedArticle
    WHERE ArtSlugHash = CHECKSUM(@Slug) AND ArtSlug = @Slug AND ArtApproved = 1
    
    SELECT a.ArtID, a.ArtUserID, a.ArtTitle, a.ArtHtml, a.ArtDescription, a.ArtKeywords, a.ArtLicenseID,
        l.licTitle, a.ArtViews, a.ArtCreated, a.ArtUpdated, s.SubID, s.SubTitle, c.CatID, c.CatTitle,
        sec.SecID, sec.SecTitle, u.UsrDisplayName AS UserName
        FROM @UpdatedArticle a
        INNER JOIN Subcategory s ON a.ArtSubcategoryID = s.SubID
        INNER JOIN Category c ON s.SubCatID = c.CatID
        INNER JOIN [Section] sec ON c.CatSectionID = sec.SecID
        INNER JOIN [User] u ON a.ArtUserID = u.UsrID
        INNER JOIN License l ON a.ArtLicenseID = l.LicID
    

1 个答案:

答案 0 :(得分:2)

以下是在单个更新语句中使用OUTPUT语句(SQL Server 2005以上版)的方法:

IF OBJECT_ID ('Books', 'U') IS NOT NULL
    DROP TABLE dbo.Books;

CREATE TABLE dbo.Books
(
  BookID int NOT NULL PRIMARY KEY,
  BookTitle nvarchar(50) NOT NULL,
  ModifiedDate datetime NOT NULL,
  NumViews int not null CONSTRAINT DF_Numviews DEFAULT (0)
);

INSERT INTO dbo.Books
  (BookID, BookTitle, ModifiedDate) 
VALUES
  (106, 'abc', GETDATE()),
  (107, 'Great Expectations', GETDATE());


-- declare @UpdateOutput1 table variable 
DECLARE @UpdateOutput1 table
(
  BookID int,
  BookTitle nvarchar(50),
  ModifiedDate datetime,
  NumViews int 
);


-- >>>>  here is the update of Numviews and the Fetch
-- update Numviews in Books table, and retrive the row
UPDATE Books
SET 
  NumViews = NumViews + 1
OUTPUT
    INSERTED.BookID,
    INSERTED.BookTitle,
    INSERTED.ModifiedDate,
    INSERTED.NumViews
  INTO @UpdateOutput1
WHERE BookID = 106

-- view updated row in Books table
SELECT * FROM Books;

-- view output row in @UpdateOutput1 variable
SELECT * FROM @UpdateOutput1;