繁体   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