带条件插入的存储过程

Stored procedure with conditional insert

我正在尝试使用 If 语句编写过程。

这是我的数据库

我的想法是:当我们有相同的ComandmentNumber时,StudentNumber必须增加1,但是当我们有新的ComandmentNumber时,StudentNumber必须从1开始。

示例:

这是我在 SQL 服务器

中的程序
CREATE PROCEDURE InsertIntoDefeatsGraduates
    @ComandmentNumber VARCHAR(100),
    @StudentFakNumber INT
AS
BEGIN
    DECLARE @StudentNumber INT 

    IF EXISTS (SELECT * FROM dbo.[Defeats-Graduates] 
               WHERE ComandmentNumber = @ComandmentNumber) 
    BEGIN
        SET @StudentNumber += 1

        INSERT INTO dbo.[Defeats-Graduates] (ComandmentNumber, StudentNumber, StudentFakNumber) 
        VALUES (@ComandmentNumber, @StudentNumber, @StudentFakNumber)
    END
    ELSE
    BEGIN
        SET @StudentNumber = 1

        INSERT INTO dbo.[Defeats-Graduates](ComandmentNumber, StudentNumber, StudentFakNumber) 
        VALUES (@ComandmentNumber, @StudentNumber, @StudentFakNumber)
    END
END

但是当我尝试执行此操作时,出现此错误:

Cannot insert the value NULL into column 'StudentNumber', table 'Test.dbo.Defeats-Graduates'; column does not allow nulls. INSERT fails.

你永远不会初始化你的@StudentNumber - 你只是声明它 - 然后它是NULL - 并将+1添加到NULL 仍然是 NULL - 所以最后,你试图将 NULL 插入你的 table

-- at this point, @StudentNumber is NULL 
DECLARE @StudentNumber INT 

IF EXISTS (SELECT * FROM dbo.[Defeats-Graduates] 
           WHERE ComandmentNumber = @ComandmentNumber) 
BEGIN
    -- trying to increment a NULL value still results in NULL
    SET @StudentNumber += 1

    -- here you're about to insert NULL into "StudentNumber"
    INSERT INTO dbo.[Defeats-Graduates] (ComandmentNumber, StudentNumber, StudentFakNumber) 
    VALUES (@ComandmentNumber, @StudentNumber, @StudentFakNumber)

你需要做的是读取实际值在它存在的情况下:

IF EXISTS (SELECT * FROM dbo.[Defeats-Graduates] 
           WHERE ComandmentNumber = @ComandmentNumber) 
BEGIN
    -- get the highest value and increment by one
    SELECT @StudentNumber = MAX(StudentNumber) + 1
    FROM dbo.[Defeats-Graduates] 
    WHERE ComandmentNumber = @ComandmentNumber;

注意SELECT MAX()+1方法非常容易产生重复值,如果你有一个繁忙的系统多个客户端同时工作和插入数据。只要有可能,您应该使用适当的 数据库提供的 机制 - 类似于 SQL 服务器中的 SEQUENCE 或类似的东西,其设计和构建是为了提供独特的价值,即使在高强度的工作负荷下。

第一个条件@StudentNumber没有赋值语句,你可以试试这个:

CREATE PROCEDURE InsertIntoDefeatsGraduates
    @ComandmentNumber VARCHAR(100),
    @StudentFakNumber INT
AS
BEGIN
    DECLARE @StudentNumber INT 
    SELECT @StudentNumber = StudentNumber  FROM dbo.[Defeats-Graduates] 
               WHERE ComandmentNumber = @ComandmentNumber
    IF ISNULL(@StudentNumber, 0) > 0
      BEGIN
        SET @StudentNumber += 1

        INSERT INTO dbo.[Defeats-Graduates] (ComandmentNumber, StudentNumber, StudentFakNumber) 
        VALUES (@ComandmentNumber, @StudentNumber, @StudentFakNumber)
      END
    ELSE
      BEGIN
        SET @StudentNumber = 1

        INSERT INTO dbo.[Defeats-Graduates](ComandmentNumber, StudentNumber, StudentFakNumber) 
        VALUES (@ComandmentNumber, @StudentNumber, @StudentFakNumber)
      END
    END