【问题标题】:How do I insert rows and move the rest down based on a sort order number?如何根据排序顺序号插入行并向下移动其余行?
【发布时间】:2013-05-25 20:49:15
【问题描述】:

如何创建一个按排序顺序(排名列)将记录插入表中并将其余部分向下移动的过程。例如,我的 sp 接收 PhysID(FK)UserID(FK)UserRoleID(FK) 的输入,它们具有必须是唯一组合的约束,最后一个输入 SortOrder 确定组合在表和该排序顺序之后的每条记录都会向下移动(或将排序顺序加 1)以为插入的行腾出空间。

每个physid 有三个roleid 选项。每个userid 可以担任3 个角色中的任何一个,但每个physid 不得超过一个。每个roleid 都有备份userids 每个physid。一旦 userid 被用于某个 physid 下的任何角色,userid 就不再是选择的候选对象。

完成后,如何根据排序顺序号插入记录,通过添加1来更新具有相同或更高排序顺序的所有记录,从而将它们按排序顺序向下移动。

这是我的代码:

CREATE PROCEDURE dbo.SP_InsertRole 
    @PhysID int,
    @UserID int,
    @UserRoleID tinyint,
    @SortOrder int
AS
BEGIN TRANSACTION
    BEGIN TRY
    BEGIN   
        UPDATE dbo.Physicians_Users
        SET SortOrder = SortOrder + 1
        WHERE @PhysID = PhysicianID AND UserRoleID = @UserRoleID AND @SortOrder >= @SortOrder
    END
    BEGIN
        SELECT @UserID = UserID FROM dbo.Users 
        IF not exists(SELECT UserID FROM dbo.Physicians_User WHERE PhysiciansID = @PhysID AND @UserID = UserID)
        INSERT INTO dbo.Physicians_Users(PhysicianID,UserID,UserRoleID,SortOrder)
        VALUES(@PhysID,@UserID,@UserRoleID,@SortOrder)
    END
    COMMIT TRANSACTION
    END TRY
BEGIN CATCH
    SELECT @@ERROR
    ROLLBACK TRANSACTION
END CATCH

RETURN 0 

GO

【问题讨论】:

  • 在WHERE子句的最后,粘贴时SortOrder好像被截断了。
  • 您使用的是什么数据库系统?

标签: sql sorting move


【解决方案1】:

试试这个SP

CREATE PROCEDURE dbo.SP_InsertRole 
@PhysID int,
@UserID int,
@UserRoleID tinyint,
@SortOrder int
AS
BEGIN TRANSACTION
  BEGIN TRY                    
    IF NOT EXISTS(
                  SELECT 1
                  FROM dbo.Physicians_User
                  WHERE PhysiciansID = @PhysID AND UserRoleID = @UserRoleID
                    AND UserID = @UserID
                  )
    BEGIN
      INSERT INTO dbo.Physicians_Users(PhysicianID, UserID, UserRoleID, SortOrder)
      VALUES (@PhysID, @UserID, @UserRoleID, @SortOrder)

      UPDATE dbo.Physicians_Users
      SET SortOrder = SortOrder + 1
      WHERE @PhysID = PhysicianID AND UserRoleID = @UserRoleID
        AND SortOrder >= @SortOrder
    END

    COMMIT TRANSACTION
  END TRY
BEGIN CATCH
  SELECT @@ERROR
  ROLLBACK TRANSACTION
END CATCH

RETURN 0 

GO

【讨论】:

    【解决方案2】:

    试试这些版本的查询。我认为您将函数的标量参数与列名混淆了:

    BEGIN   
        UPDATE dbo.Physicians_Users
            SET SortOrder = SortOrder + 1
            WHERE @PhysID = PhysicianID AND UserRoleID = @UserRoleID AND
                  SortOrder >= @SortOrder;   -- <-- this is the line that changed
    END
    BEGIN
        SELECT @UserID = UserID FROM dbo.Users;
        IF not exists(SELECT UserID
                      FROM dbo.Physicians_User
                      WHERE PhysiciansID = @PhysID AND @UserID = UserID)
        INSERT INTO dbo.Physicians_Users(PhysicianID,UserID,UserRoleID,SortOrder)
            VALUES(@PhysID,@UserID,@UserRoleID,@SortOrder)
    END
    

    这修正了语法。您也可以通过以下方式表达 insert 而没有 if

        INSERT INTO dbo.Physicians_Users(PhysicianID,UserID,UserRoleID,SortOrder)
            select @PhysID, @UserID, @UserRoleID, @SortOrder
            where not exists(SELECT UserID
                      FROM dbo.Physicians_User
                      WHERE PhysiciansID = @PhysID AND @UserID = UserID)
    

    逻辑仍然不太正确。如果记录已经在表中,为什么要更新sortorder。而且,如果记录在表中,您可能应该更新该记录的排序顺序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-17
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-12
      • 1970-01-01
      相关资源
      最近更新 更多