Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 存储过程c上的多个ExecuteOnQuery#_C#_Sql Server_Stored Procedures_Transactions - Fatal编程技术网

C# 存储过程c上的多个ExecuteOnQuery#

C# 存储过程c上的多个ExecuteOnQuery#,c#,sql-server,stored-procedures,transactions,C#,Sql Server,Stored Procedures,Transactions,我想使用相同的连接和相同的事务,使用不同的参数执行相同的存储过程。 理想情况下,如果对ExecuteNonQuery()的任何调用失败,则应回滚整个事务 存储过程:Sample1 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[Sample1] @start_date datetime, @end_date datetime, @empID int WITH EXEC AS CALLER AS BEG

我想使用相同的连接和相同的事务,使用不同的参数执行相同的存储过程。
理想情况下,如果对
ExecuteNonQuery()
的任何调用失败,则应回滚整个事务

存储过程:Sample1

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Sample1]
@start_date datetime, @end_date datetime, @empID int
WITH EXEC AS CALLER
AS
BEGIN
BEGIN TRANSACTION;
BEGIN TRY
   -- set of insert, delete and update
COMMIT TRANSACTION;
END TRY

BEGIN CATCH
Declare @ErrorMessage Varchar(100), @ErrorNumber Int 

   SELECT ERROR_NUMBER() AS ErrorNumber ,ERROR_MESSAGE() AS ErrorMessage;
   ROLLBACK TRANSACTION;
  RAISERROR(@ErrorMessage,@ErrorNumber,1);

END CATCH;

END
我的C代码

public int ExecuteSP()
{ 
var connectionString=ConfigurationManager.AppSettings[“\uuu WaveDatabaseConnection”];
int rowsAffected=0;
使用(var连接=新的SqlConnection(connectionString))
{
connection.Open();
var transaction=connection.BeginTransaction();
尝试
{
var command=newsqlcommand(_StoreProcedureName,connection){CommandType=CommandType.StoredProcedure};
command.CommandType=CommandType.storedProcess;
command.Connection=连接;
command.Transaction=事务;
Add(“@empid”,SqlDbType.Int).Value=site.ID;
command.Parameters.Add(“@start_date”,SqlDbType.DateTime).Value=new DateTime();
Add(“@end_date”,SqlDbType.DateTime).Value=new DateTime();
对于(i=0;i<10;i++)
{
command.Parameters[“@start_date”].Value=new DateTime().Add(i);
command.Parameters[“@end_date”].Value=new DateTime().Add(i+1);
rowsAffected+=command.ExecuteNonQuery();
}
Commit();
}
捕获(SqlException SqlException)
{
var sqlExceptionMessage=string.Format(“错误号:{0},错误类型:{1}错误消息:{2}”,
sqlException.ErrorCode、sqlException.GetType()、sqlException.Message);
尝试
{
transaction.Rollback();
}
捕获(异常)
{
sqlExceptionMessage=
Format(“ExecuteError:{0},回滚异常错误类型:{1}错误消息:{2}”,
sqlExceptionMessage,exception.GetType(),exception.Message);
}
抛出新异常(sqlExceptionMessage);
}
}
返回受影响的行;
}
}
现在我得到了这个例外

EXECUTE后的事务计数表示BEGIN和COMMIT语句的数量不匹配。上一次计数=1,当前计数=0

当我从存储过程中删除所有的
BEGIN TRANS/COMMIT/ROLLBACK
语句时,第一个
命令.ExecuteNonQuery()
将毫无问题地执行。
当第二次调用它时,它会抛出以下异常:

在批处理结束时检测到不可提交的事务。事务被回滚

我甚至试着在SP中使用
设置XACT\u ABORT ON
,但没有效果

请帮助我如何提交全部或回滚C#代码,以及如何解决上述问题

谢谢
Vijay

可能重复@GSerg,但当我删除SP上的所有事务时,会出现不同的错误。理想情况下,我只想在c#级别控制事务。你能帮我看一下如何实现它的代码吗?看看这篇关于SQL Server神话的文章——神话嵌套事务是真实的——让存储过程在没有事务的情况下执行多个语句是错误的。让C#代码在不启动事务的情况下调用多个SP也是错误的。正如Steve Ford所注意到的,因为实际上没有真正的嵌套事务,所以不能通过将begin trans与相同数量的回滚匹配来平衡代码。相反,您应该使用一种模式,例如,只有在当前级别上启动事务时才回滚事务。例如,您应该从SP检测到存在环境事务,如果存在,请不要回滚。请查看本博客,其中解释了16级SQL Server错误何时会导致这些症状。您需要检查XACT_状态以确定事务是否可提交。
public int ExecuteSP()
{ 
   var connectionString = ConfigurationManager.AppSettings["__WaveDatabaseConnection"];
          int rowsAffected = 0;
          using (var connection = new SqlConnection(connectionString))
          {
            connection.Open();
            var transaction = connection.BeginTransaction();
            try
            {

          var command = new SqlCommand(_StoreProcedureName, connection) { CommandType = CommandType.StoredProcedure };
          command.CommandType = CommandType.StoredProcedure;
          command.Connection = connection;
          command.Transaction = transaction;
          command.Parameters.Add("@empid", SqlDbType.Int).Value = site.ID;
          command.Parameters.Add("@start_date", SqlDbType.DateTime).Value = new DateTime();
          command.Parameters.Add("@end_date", SqlDbType.DateTime).Value = new DateTime();

          for (i = 0; i < 10; i++))
          {
            command.Parameters["@start_date"].Value = new DateTime().Add(i);
            command.Parameters["@end_date"].Value = new DateTime().Add(i+1);
            rowsAffected += command.ExecuteNonQuery();
          }
          transaction.Commit();
        }
        catch (SqlException sqlException)
        {
          var sqlExceptionMessage = string.Format("Error number : {0}, Error Type : {1} Error message : {2}",
            sqlException.ErrorCode, sqlException.GetType(), sqlException.Message);

          try
          {
            transaction.Rollback();
          }
          catch (Exception exception)
          {
            sqlExceptionMessage =
              string.Format("ExecuteError : {0}, RollBack exception Error Type : {1} Error message : {2}",
                sqlExceptionMessage, exception.GetType(), exception.Message);
          }
          throw new Exception(sqlExceptionMessage);
        }
      }
      return rowsAffected;
    }
}