【问题标题】:Check transaction committed and if so return a value检查已提交的事务,如果是,则返回一个值
【发布时间】:2019-06-24 04:13:15
【问题描述】:

我想在用户表中插入一个新用户(电子邮件地址)。如果成功(不重复),将新用户的基本配置插入其他表,并将一些数据返回给客户端。如果不成功,在 C# 项目的数据集中接收相关通知。

这里是示例代码,您可以轻松地对其进行评论

ALTER PROCEDURE [dbo].[CreateUser] 
  @Email nvarchar(256),   
  @Password nvarchar(256)   
AS
BEGIN
  declare @UserID uniqueidentifier;
  declare @ConfigID uniqueidentifier;
  declare @TopMostNode uniqueidentifier;

  BEGIN TRANSACTION;
    select @UserID = NEWID();
    select @ConfigID = newid();

    insert into Users (UserID,Email,Password,CurrentConfig) 
      values(@UserID, @Email, @Password, @ConfigID);

    INSERT INTO Configs (ConfigID, OwnerID, DisplayName, LastPrintID)
      VALUES (@ConfigID,@UserID, 'Default Config', 1);

  COMMIT TRANSACTION 
END

【问题讨论】:

  • 您需要详细说明问题。 1. 操作不成功(用户存在)会收到什么样的通知。 2、你想返回给客户端的“一些数据”究竟是什么?
  • 您面临的实际问题是什么?
  • 您好,目前还没有实际问题。如果交易不成功,我想通过错误或零返回值,甚至是异常来在客户端得到通知。我要返回的数据只是@UserID 和@ConfigID。我不知道在哪里放置 select 语句,或者我需要在 select 之前检查一些东西...

标签: sql-server stored-procedures return-value commit


【解决方案1】:

这是一种可能性,您可以返回一个包含所需数据的记录集和一个指示用户是否已存在的标志。

alter procedure [dbo].[CreateUser]
(
  @Email nvarchar(256)  
  , @Password nvarchar(256)
)
as
begin
  declare @UserID uniqueidentifier, @ConfigID uniqueidentifier, @TopMostNode uniqueidentifier, @UserExists bit = 0;

  select @UserID = UserID, @UserExists = 1 from Users where Email = @Email;

  if @UserExists = 0 begin
    begin transaction;
      set @UserID = newid();
      set @ConfigID = newid();

      insert into Users (UserID, Email, [Password], CurrentConfig) 
        values (@UserID, @Email, @Password, @ConfigID);

      insert into Configs (ConfigID, OwnerID, DisplayName, LastPrintID)
        values (@ConfigID, @UserID, 'Default Config', 1);

    commit transaction 
  end

  -- Return whether the user already exists or not and the user id
  select @UserExists, @UserId

  return 0;
end

另一种向应用返回数据的方法是使用output 参数,例如

alter procedure [dbo].[CreateUser]
(
  @Email nvarchar(256)  
  , @Password nvarchar(256)
  , @UserId uniqueidentifier out
  , @UserExists bit out
)
as
begin
  declare @ConfigID uniqueidentifier, @TopMostNode uniqueidentifier;

  set @UserExists = 0;

  select @UserID = UserID, @UserExists = 1 from Users where Email = @Email;

  if @UserExists = 0 begin
    begin transaction;
      set @UserID = newid();
      set @ConfigID = newid();

      insert into Users (UserID, Email, [Password], CurrentConfig) 
        values (@UserID, @Email, @Password, @ConfigID);

      insert into Configs (ConfigID, OwnerID, DisplayName, LastPrintID)
        values (@ConfigID, @UserID, 'Default Config', 1);

    commit transaction 
  end

  return 0;
end

【讨论】:

    【解决方案2】:

    该代码几乎完成了。只需添加一个 SELECT 即可返回新键。如果发生错误,您将收到异常。例如:

    ALTER PROCEDURE [dbo].[CreateUser] 
      @Email nvarchar(256),   
      @Password nvarchar(256)   
    AS
    BEGIN
      declare @UserID uniqueidentifier;
      declare @ConfigID uniqueidentifier;
      declare @TopMostNode uniqueidentifier;
    
      BEGIN TRANSACTION;
        select @UserID = NEWID();
        select @ConfigID = newid();
    
        insert into Users (UserID,Email,Password,CurrentConfig) 
          values(@UserID, @Email, @Password, @ConfigID);
    
        INSERT INTO Configs (ConfigID, OwnerID, DisplayName, LastPrintID)
          VALUES (@ConfigID,@UserID, 'Default Config', 1);
    
      COMMIT TRANSACTION 
      select @UserID UserID, @ConfigID ConfigID;
    END
    

    【讨论】:

    • 谢谢,所以,如果交易不成功,我会在客户端收到异常通知。
    • 正确。如果任一语句失败,您将获得异常。
    猜你喜欢
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 2013-11-20
    • 2020-12-06
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多