1

我有一个按钮事件,在达到一定数量的用户后必须自行禁用。

我们正在将当前访问的用户计数存储在数据库中,并且我正在尝试创建一个存储过程,当调用该存储过程时,它将自动增加该表上的用户计数。
我将创建一个单独的过程来减去。

在我看来,我需要获取当前值,添加一个,然后将其保存在表中,将我带到以下代码:

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.

4

4 回答 4

2
SET @count = UserCount 

是不正确的。您不能SELECT像这样访问先前语句中的列。

您可以在一个原子语句中完成所有操作。这会增加列并将输出参数设置为 UserCount 的新值。

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

这避免了竞争条件在单独的操作中读取和写入值。

于 2012-11-20T12:44:22.240 回答
1

对于参考案例,它应该是这样的

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 中设置
于 2012-11-20T12:46:41.997 回答
1

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

从 tblDrRefBooks 中选择 @count=UserCount,其中 DrRefBookFileID = @fileId

于 2012-11-20T12:49:08.080 回答
0

无需使用临时变量和使用选择查询。试试这个..

UPDATE tblDrRefBooks 
SET tblDrRefBooks.UserCount = UserCount +1 
WHERE DrRefBookFileID = @fileId
于 2012-11-21T07:30:02.343 回答