如何在达到限制时停止在SQL表中插入记录

时间:2009-09-25 06:01:28

标签: sql sql-server vb.net

我正在使用VB.net和SQL Server 2005。

我的问题是,如果达到该课程的委托限制,我想给用户一条消息。

请参阅我的课程,其中 MinDelegate MaxDelegate 限制。我想停止插入并向用户发送消息“最大代表限制已达到此课程不能有更多代表”

以下是插入命令,它在我的委托表中插入记录。

ALTER PROCEDURE [dbo].[uspInsertDelegate]
(
    @CourseID int,
    @CPUserID int,
    @StatusID int,
    @CreateUser varchar(25),
    @CourseDate smalldatetime

)
AS
    SET NOCOUNT OFF;
IF NOT EXISTS (SELECT *
        FROM tblDelegate
        WHERE CourseID = @CourseID and CPUserID = @CPUserID)
BEGIN
INSERT INTO tblDelegate                      
(
    CourseID, 
    CPUserID, 
    StatusID, 
    CreateUser 

)
VALUES     
(
    @CourseID,
    @CPUserID,
    @StatusID,
    @CreateUser
)
END

UPDATE tblTraining
SET 
TrainingDT = @CourseDate,
TrainingCompleted = @StatusID
WHERE CPUserID = @CPUserID

RETURN

还请建议在VB.NET代码中做什么!

谢谢!

最诚挚的问候,

YUV

5 个答案:

答案 0 :(得分:2)

解决方案是编写一个“INSERT之前”触发器,该触发器将通过检查有多少学生注册该类等来强制执行业务规则,并防止插入发生。

然后可以在更高级别检测到此错误情况,并向用户提供正确的错误消息。

在重新阅读您的问题时,业务规则也可以在您现有的存储过程中进行检查,然后只需要使存储过程返回条件代码(比如整数:0 =插入ok和-1 = class is full),并在应用程序级别测试此值。

修改:更多详细信息(但不完整代码......)

Yuvraj,这看起来非常像 家庭作业 ,所以我想让你走上正确的轨道,但也让你工作到足以让你学习这个过程搞清楚事情。

关于商店程序(SP),bniwredyc随时为您提供了以下代码: 与您的问题相比,这是一个小小的修改:

@minDelegate int,
@maxDelegate int

set @delegatesCount = (select count(*) from tblDelegate 
                       where CourseID = @CourseId)

if (@delegatesCount >= maxDelegate)
        return -1  

基本上你在程序中添加2个额外的参数:minDelegate和maxDelegate以及从过程中提前返回,返回值为-1 ,以防万一与会代表。 (在bniwredyc的例子中有1个,但我更喜欢错误条件的负值)。我认为minDelegate根本不被使用;你知道哪些规则必须适用......

现在,您需要编写一个VB程序,它将通过ADO 调用此SP。这将涉及使用ADODB.Command对象此Microsoft MSDN page提供有关此对象的参考信息,并且在离此页不太远的几个链接之后,您还将找到有关Connection对象和RecordSet对象的详细信息。

存储过程有三种方法可以将某些数据返回给调用方法。

    1. By returning an integer value in the RETURN value.  This value is 
       the return value of the Command object's Execute() method. 
       This is the simpler approach and can be used in your case
    2. By returning values (integer, text or other) in one or several OUTPUT
       Parameters
    3. By returning a recordset 

    Method 2 can be combined with 1 or 3, however 1 and 3 are mutually
    exclusive since they both use return value of the Execute() method
    to provide an integer (1) or a Recordset (3).

this page处的示例显示了您需要的所有内容,但它使用了数据的记录集,这在您的情况下是不必要的;而是使用整数值来存储Execute()的返回值,并对其进行测试。如果0:记录被添加好,If-1:失败“太多”测试。

现在,开始工作:-)并且请在适当时将您的问题标记为“家庭作业”。

答案 1 :(得分:0)

您可以创建一个只返回记录总数的验证存储过程。首先从你的VB代码中调用它,然后检查该计数,然后返回相应的错误消息,然后调用你提供的insert sproc。

答案 2 :(得分:0)

您可以使用MaxDelegates将变量传递给存储过程,并在插入之前在存储过程中进行检查

Declare @CurrentNumberOfDelegates int
Select @CurrentNumberOfDelegates = Count(*)
From tblDelegate
Where CourseId = @CourseId

If @CurrentNumberOfDelegates > @MaxDelegates
 Return -1

在这种情况下,您将在VB.Net上检查存储过程的返回值,如果为-1,则向用户显示该消息。
此解决方案应该足够安全,因为您在插入之前检查计数,但您可能需要添加事务以确保限制永远不会被同时运行的另一个线程传递。

答案 3 :(得分:0)

我认为您可以将此代码用于存储过程:

ALTER PROCEDURE [dbo].[uspInsertDelegate]
    (
        @CourseID int,
        @CPUserID int,
        @StatusID int,
        @CreateUser varchar(25),
        @CourseDate smalldatetime,
        @minDelegate int,
        @maxDelegate int
    )
    AS
        SET NOCOUNT OFF;
    IF NOT EXISTS (SELECT *
            FROM tblDelegate
            WHERE CourseID = @CourseID and CPUserID = @CPUserID)
    BEGIN
        set @delegatesCount = (select count(*) from tblDelegate where CourseID = @CourseId)

        if (@delegatesCount >= maxDelegate)
            return 1
        else
        begin
            INSERT INTO tblDelegate                      
            (
                CourseID, 
                CPUserID, 
                StatusID, 
                CreateUser 
            )
            VALUES     
            (
                @CourseID,
                @CPUserID,
                @StatusID,
                @CreateUser
            )
        end
    END

    UPDATE tblTraining
    SET 
    TrainingDT = @CourseDate,
    TrainingCompleted = @StatusID
    WHERE CPUserID = @CPUserID

    RETURN 0

在VB代码中,只检查执行存储过程返回的值:如果它超过了最大委托限制。您还可以向存储过程添加一些代码,以便在达到最小限制时返回值。

答案 4 :(得分:0)

首先感谢回答我问题的所有成员

我使用以下逻辑解决了这个问题

在Sql程序中,我改变了我的程序。

ALTER PROCEDURE [dbo].[uspInsertDelegate]
(
    @CourseID int,
    @CPUserID int,
    @StatusID int,
    @CreateUser varchar(25),
    @CourseDate smalldatetime,
    @MaxDelegate int

)
AS
    SET NOCOUNT OFF;
IF NOT EXISTS (SELECT * FROM tblDelegate WHERE CourseID = @CourseID and CPUserID = @CPUserID)
BEGIN
    Declare @DelegateBooked int
    set @DelegateBooked = (SELECT count(*) FROM tblDelegate WHERE CourseID = @CourseID)
    IF @DelegateBooked >= @MaxDelegate
        SELECT 1
    ELSE
    BEGIN
        INSERT INTO tblDelegate                      
        (
            CourseID, 
            CPUserID, 
            StatusID, 
            CreateUser 

        )
        VALUES     
        (
            @CourseID,
            @CPUserID,
            @StatusID,
            @CreateUser
        )

        UPDATE tblTraining
        SET 
        TrainingDT = @CourseDate,
        TrainingCompleted = @StatusID
        WHERE CPUserID = @CPUserID
    END
END

在我的VB.net代码中,我写道:

Protected Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSave.Click
        If Not Session("CourseDate") Is Nothing Then
            Try
                Dim conString As String = WebConfigurationManager.ConnectionStrings("LocalSqlServer").ConnectionString
                Dim con As New SqlConnection(conString)
                con.Open()
                Dim cmd As SqlCommand
                For Each curRow As GridViewRow In GridView1.Rows
                    Dim chkSelect As CheckBox = CType(curRow.Cells(1).FindControl("chkSelect"), CheckBox)
                    If chkSelect.Checked Then
                        cmd = New SqlCommand("uspInsertDelegate", con)
                        cmd.CommandType = CommandType.StoredProcedure
                        cmd.Parameters.Add("@CourseID", SqlDbType.Int).Value = Session("CourseID")
                        cmd.Parameters.Add("@CPUserID", SqlDbType.Int).Value = CType(curRow.Cells(1).FindControl("lblCPUserID"), Label).Text
                        cmd.Parameters.Add("@StatusID", SqlDbType.Int).Value = 25
                        cmd.Parameters.Add("@CreateUser", SqlDbType.VarChar).Value = Session("LoggedInUser")
                        cmd.Parameters.Add("@CourseDate", SqlDbType.DateTime).Value = Session("CourseDate")
                        cmd.Parameters.Add("@MaxDelegate", SqlDbType.Int).Value = Session("MaxDelegate")
                        Dim retValue As Integer = CType(cmd.ExecuteScalar(), Integer)
                        If retValue = 1 Then
                            lblError.Visible = True
                            lblError.Text = "Max Delegate limit has reached can't have more delegates for this course"
                            Exit For
                        Else
                            lblError.Visible = False
                        End If
                    End If
                Next
                GridView1.DataBind()
            Catch ex As Exception
                ErrorHandler.WriteError(ex.Message)
            End Try
        End If

如果错误,请查看并提供反馈