【问题标题】:Issue with Scope_identity() when used with TransactionScope()与 TransactionScope() 一起使用时 Scope_identity() 出现问题
【发布时间】:2015-08-13 07:39:53
【问题描述】:

我正在使用 TransactionScope() 这样..

SqlCommand cmd = new SqlCommand(); 
cmd.CommandType = CommandType.StoredProcedure; 
cmd.CommandText = "proc_insertlot"; cmd.Connection = sqlconn; 
da = new SqlDataAdapter(cmd);

    for (int i = 0; i < 3 i++)
    {         
          da.Fill(ds);//this insert a row in a table which has identity column
          LotId = ds.Tables[1].Rows[0][0].ToString();//always return same identityvalue
    }

//---TransactionScope 提交

似乎除非我提交事务,否则 scope_identity 不会增加。在此示例中,scope_identity 将返回相同的值 3 次。你怎么解决这个问题?

SQL:

ALTER  procedure proc_insertlot      
@AuctionId int=0,      
@Title varchar(300)='',      
@Description varchar(4000)='',      
@lottype varchar(20)='',      
@ImproveBidBy varchar(20)='',      
@BidDecrement varchar(20)='',      
@FrontBuffer varchar(20)='',      
@BackBuffer varchar(20)='',      
@AttachmentId varchar(30)='',      
@MkrId varchar(11)=''  ,    
@file_uploadlot varchar(30) =''    
as      
      set nocount on 
insert into tbl_lots(AuctionId,Title,Description,lottype,ImproveBidBy,BidDecrement,FrontBuffer,BackBuffer,AttachmentId,MkrId,MkrDt)      
 values (@AuctionId,@Title,@Description,@lottype,@ImproveBidBy,@BidDecrement,@FrontBuffer,@BackBuffer,@AttachmentId,@MkrId,GETDATE())   

select @@Identity as lotid

【问题讨论】:

  • 通常,da 是数据适配器,ds 是数据集,所以 da.Fill(ds) 从数据库中选择记录,而不是向其中插入记录......
  • @ZoharPeled SqlCommand cmd = new SqlCommand(); cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "proc_insertlot"; cmd.Connection = sqlconn; da = new SqlDataAdapter(cmd);
  • @Arbaaz - 如果您想添加更多代码,请edit 您的问题,以便您可以使用格式化工具 ({}) cmets 中的代码实际上是不可读的。
  • @Damien_The_Unbeliever .. 完成
  • @AmitRanjan - 没问题。我当然可以自己做,但我尝试鼓励 OP 做这种工作,以便他们掌握编辑的窍门,根据 cmets 改进他们的问题等。

标签: c# sql asp.net .net sql-server


【解决方案1】:

我认为它会起作用。更改行[0][0] -> 行[i][0]

for (int i = 0; i < 3 i++)
{         
      da.Fill(ds);//this insert a row in a table which has identity column
      LotId = ds.Tables[1].Rows[i][0].ToString();//will now return required identityvalue
}

看看它是否有效。

更新

有你的问题。问题是 一旦提交范围,LotId = ds.Tables[1].Rows[0][0].ToString(); 将始终返回 scope_identity 的最后一个最大值。相反,您可以尝试@@Identity。还要检查您是否使用 PK 启用了 AutoIncrement。一般我们使用 AutoIncrement Columns 作为 PK。

例如礼貌:Guffa。

    create procedure proc_insertlot
    as
    set nocount on
declare @id as int
    insert into SomeTable (
      SomeField
    ) values (
      42
    )

    SET @Id=@@Identity
    SELECT @ID

【讨论】:

  • 这将如何解决?过程中只有一个select语句 select SCOPE_IDENTITY() as lotid 值总是会在第一行返回
  • @Arbaaz - 实际上我对你的代码有点困惑。如果你知道它在 Rows[0][0] 中,那么循环的需要是什么。您是否尝试三次执行 Scope Identity 并获得三次,是这样吗?
  • 我的场景中需要循环。这只是一个简单的例子,它在一定程度上说明了我的问题。有一个插入 sql 过程 proc_insertlot 每次都会从循环中执行。这个过程有`select SCOPE_IDENTITY() as lotid`。现在假设表一开始是空白的,基本上这段代码应该在第一次执行 insert proc 时返回标识值 1,在第二次迭代时返回 2,依此类推。
  • 它仍然返回相同的值
  • 抱歉,您的第一个解决方案奏效了。我没有注意到每次执行过程时返回的结果都在新行中。
【解决方案2】:

为此,您需要:

  • 表中的一个键
  • 密钥需要设置 Identity = true
  • 程序需要set nocount on来抑制插入的结果

例子:

create procedure proc_insertlot
as

set nocount on

insert into SomeTable (
  SomeField
) values (
  42
)

select scope_identity()

【讨论】:

  • 每次仍然返回相同的值
【解决方案3】:

ExecuteScalar 用于返回最后插入记录的ID,您可以使用它返回ID

select Scope_Identity

希望这可以帮助您解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 2011-05-04
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多