【问题标题】:Stored procedure with conditional insert带条件插入的存储过程
【发布时间】:2020-09-11 17:43:57
【问题描述】:

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

这是我的数据库

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

例子:

这是我在 SQL Server 中的过程

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

但是当我尝试执行这个时,我得到了这个错误:

无法将值 NULL 插入到列“StudentNumber”、表“Test.dbo.Defeats-Graduates”中;列不允许空值。插入失败。

【问题讨论】:

    标签: sql-server procedure


    【解决方案1】:

    你永远不会初始化你的 @StudentNumber - 你只是声明它 - 然后它是 NULL - 并且将 +1 添加到 NULL 仍然是 NULL - 所以最后,你'正在尝试将 NULL 插入您的表中

    -- 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 方法非常容易产生重复值,如果您有一个繁忙的系统,多个客户端同时工作和插入数据.只要有可能,您应该使用适当的 database-provided 机制来代替 - 类似于 SQL Server 中的 SEQUENCE 或类似的东西,其设计和构建旨在提供唯一值,即使在繁重的工作负载下也是如此。

    【讨论】:

      【解决方案2】:

      在第一个条件下你没有@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
      

      【讨论】:

      • 不,在这种情况下,@StudentNumber 的值已经 > 0。
      • 其实SELECT @StudentNumber = StudentNumber FROM dbo.[Defeats-Graduates] WHERE ComandmentNumber = @ComandmentNumber会在匹配到任何记录时初始化@StudentNumber
      猜你喜欢
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多