簡體   English   中英

使用存儲過程(+1或-1)表中的值

[英]Using a stored procedure to (+1 or -1) a value from a table

我有一個按鈕事件,必須在達到一定數量的用戶后自行禁用。

我們將當前訪問的用戶計數存儲在db中,我正在嘗試創建一個存儲過程,在調用時,它將自動增加該表上的用戶計數。
我將創建一個單獨的程序來減去。

在我看來,我需要獲取當前值,添加一個,然后將其保存在表中,帶我到這個代碼:

CREATE PROCEDURE procDrRefBooksAddUser 
    -- Add the parameters for the stored procedure here
    @fileId int = NULL,
    @count int = 0,
    @newCount int OUTPUT
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    SELECT UserCount FROM tblDrRefBooks WHERE DrRefBookFileID = @fileId
    SET @count = UserCount

    SET @newCount = @count + 1

    -- Insert statements for procedure here
    UPDATE tblDrRefBooks SET tblDrRefBooks.UserCount = @newCount WHERE DrRefBookFileID = @fileId
END

不幸的是,我無法做到正確,遇到如下錯誤:

Msg 207, Level 16, State 1, Procedure procDrRefBooksAddUser, Line 17
Invalid column name 'UserCount'

有人可以告訴我哪里出錯了。

編輯:答案更新(最后)

我的SQL是:

ALTER PROCEDURE [dbo].[procDrRefBooksAddUser] 
    -- Add the parameters for the stored procedure here
    @fileId int = NULL,
    @newCount int OUTPUT
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    -- SET NOCOUNT ON;

    UPDATE tblDrRefBooks
    SET @newCount = UserCount = UserCount + 1
    WHERE DrRefBookFileID = @fileId
    SELECT @newCount AS iden

END

而代碼背后是:

 using (SqlConnection db = DataConn.SqlConnection())
                {
                    db.Open();
                    SqlTransaction transaction = db.BeginTransaction();

                    try
                    {
                        lbltest.Text = "Starting...";
                       using (SqlCommand acommand =
                            new SqlCommand(
                                "EXEC procDrRefBooksAddUser @fileID, @count",
                                db, transaction) { CommandType = CommandType.Text })
                        {
                            acommand.Parameters.Add(new SqlParameter("@fileID", SqlDbType.Int)).Value = Int32.Parse(location.Value);
                            acommand.Parameters.Add(new SqlParameter("@count", SqlDbType.Int) { Direction = ParameterDirection.Output });

                            using (SqlDataReader rdr = acommand.ExecuteReader())
                            {
                                btnLoad.Text = "Here: " + rdr["iden"];
                            }
                        }

                        transaction.Commit();
                    }
                    catch (Exception ea)
                    {
                        transaction.Rollback();
                        lbltest.Text = ("Insertion Error: " + ea.Message);
                    }
                }

但我收到此錯誤: Insertion Error: Invalid attempt to read when no data is present.

SET @count = UserCount 

是不正確的。 您無法像以前那樣訪問之前SELECT語句中的列。

你可以在一個原子語句中完成所有操作。 這會使列遞增,並使用UserCount的新值設置輸出參數。

UPDATE tblDrRefBooks
SET    @newCount = UserCount = UserCount + 1
WHERE  DrRefBookFileID = @fileId 

這避免了競爭條件在單獨的操作中讀取和寫入值。

對於參考案例,它應該是這樣的

SELECT @Count = UserCount FROM tblDrRefBooks WHERE DrRefBookFileID = @fileId
@newCount = @Count + 1

但你可以避免這種情況,而是這樣做

UPDATE tblDrRefBooks SET UserCount = UserCount + 1
WHERE 
   DrRefBookFileID = @fileId AND
   UserCount < @MaxUserCount

更新

注意我添加了AND UserCount < @MaxUserCount 由於頁面快速刷新[競爭條件],您的存儲過程可能無法捕獲所有計數。 您可能有一個舊的@Count值。

  • 如果未達到MAX,請確保僅增加計數
  • 只需在任何時間點與另一個PROC獲取計數。 不要在與更新計數相同的PROC中執行此操作,因為您可以獲得OLD計數值
  • 達到MAX后,可以在PROC上有一個SET標志

在您的程序中使用以下代碼:

SELECT @ count = UserCount FROM tblDrRefBooks WHERE DrRefBookFileID = @fileId

無需使用臨時變量和使用select查詢。 嘗試這個..

UPDATE tblDrRefBooks 
SET tblDrRefBooks.UserCount = UserCount +1 
WHERE DrRefBookFileID = @fileId

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM