Command executenonquery ошибка

При создании SqlConnection необходимо явно указывать поле Connection, иначе оно автоматически инициализируется в null.

Честно говоря, я не знаю, почему API позволяет конструировать невалидные объекты, но думаю, что это не design flaw, а все-таки служит какой-то цели.

В вашем случае нужно использовать:

var command = new SqlCommand(Query, Connection);

Кстати, да. SqlConnection — это IDisposable. Соответственно, если вы храните его как поле в вашем классе, то не обходимо делать класс IDisposable и предоставлять методы для освобождения ресурсов (иначе в ближайшем будущем вы можете столкнуться с проблемами).

Более простой вариант — использовать connection в локальном скоупе через using.


Ваш текущий вариант с using неправильный, т.к произойдет следующее:

  • В методе Connect будет создан объект Connection.
  • После первого вызова метода SQLWithoutFetch (на выходе из using блока) будет неявно вызван Connection.Dispose().
  • При любой следующей попытке вызвать SQLWithoutFetch вы (в лучшем случае) получите ObjectDisposedException, поскольку объект был освобожден в предыдущем вызове.

Как решать это я написал выше.


Еще одно замечание:

catch (SqlException)
{
    throw new Exception("Bad SQL query");
}

Заменять конкретный SqlException с параметрами ошибки на общий Exception недопустимо. try-catch здесь вообще не нужен, т.к вы не можете ничего сделать внутри этого метода, чтобы исправить ошибочную ситуацию.

Обработка ошибок должна быть уровнем выше, следовательно, автоматически проброшенный SqlException — это хорошо.


А, и еще:

if (Connection.State == ConnectionState.Open) ...

I have a very strange problem that only occurs when the code in question is in a high load situations. My ASP.NET web client C# code calls a T-SQL stored procedure that has an OUTPUT parameter.

Under high loads, the data being returned sometimes does not make it back to the calling C# code. I have extracted all the relevant code into the example below;

Stored procedure:

CREATE PROCEDURE GetLoginName
    @LoginId BIGINT,
    @LoginName VARCHAR(50) OUTPUT
AS
   SET NOCOUNT ON

   SELECT @LoginName = LoginName
   FROM Logins
   WHERE Id = @LoginId

   SET NOCOUNT OFF
GO

Database base class:

public class DatabaseContextBase : IDisposable
{
    private SqlConnection _connection;
    private string _connectionString;
    private SqlInt32 _returnValue;
    private int _commandTimeout;
    private static int _maxDatabaseExecuteAttempts = 3;   

    private static int s_commandTimeout = 30;

    protected DBContextBase()
    {
        // try and get the connection string off the identity first...
        string connectionString = GetConnectionStringFromIdentity();

        if(connectionString != null)
        {
            ConstructionHelper(connectionString, s_commandTimeout);
        }
        else
        {
            // use the initialised static connection string, and call the other overload
            // of the constructor
            ConstructionHelper(s_connectionString, s_commandTimeout);
        }   
    }

    private void ConstructionHelper( string connectionString, int commandTimeout ) 
    {
        // store the connection string in a member var.
        _connectionString = connectionString;

        // store the timeout in a member var.
        _commandTimeout = commandTimeout;
    }

    public static string GetConnectionStringFromIdentity()
    {
        IIdentity identity = Thread.CurrentPrincipal.Identity as wxyz.Security.wxyzIdentityBase;
        string connectionString = null;

        if(identity != null)
        {
            connectionString = ((wxyz.Security.wxyzIdentityBase) identity ).ConnectionString;
        }

        return connectionString;
    }

    public void Dispose()
    {           
        if (_connection.State != ConnectionState.Closed)
        {
            _connection.Close();
        }

        _connection.Dispose();
        _connection = null;
    }

    protected void ExecuteNonQuery(SqlCommand command)
    {
        SqlConnection con = this.Connection;

        lock (con)
        {
            if (con.State != ConnectionState.Open)
            {
                con.Open();
            }

            // don't need a try catch as this is only ever called from another method in this 
            // class which will wrap it.
            command.Connection = con;
            command.Transaction = _transaction;
            command.CommandTimeout = _commandTimeout;

            for (int currentAttempt = 1; currentAttempt == _maxDatabaseExecuteAttempts; currentAttempt++)
            {
                try
                {
                    // do it
                    command.ExecuteNonQuery();

                    // done, exit loop
                    break;
                }
                catch (SqlException sex)
                {
                    HandleDatabaseExceptions(currentAttempt, sex, command.CommandText);
                }
            }
        }   
    }

    protected void HandleDatabaseExceptions(int currentAttempt, SqlException sqlException, string sqlCommandName)
    {
        if (DataExceptionUtilities.IsDeadlockError(sqlException))
        {
            if (!this.IsInTransaction)
            {
                // Not in a transaction and a deadlock detected.
                // If we have not exceeded our maximum number of attemps, then try to execute the SQL query again.
                string deadlockMessage = string.Format("Deadlock occured in attempt {0} for '{1}':", currentAttempt, sqlCommandName);
                Logging.Write(new ErrorLogEntry(deadlockMessage, sqlException));

                if (currentAttempt == DBContextBase.MaxDatabaseExecuteAttempts)
                {
                    // This was the last attempt so throw the exception
                    throw sqlException;
                }

                // Wait for a short time before trying again
                WaitShortAmountOfTime();
            }
            else
            {
                // We're in a transaction, then the calling code needs to handle the deadlock
                string message = string.Format("Deadlock occured in transaction for '{0}':", sqlCommandName);

                throw new DataDeadlockException(message, sqlException);
            }
        }
        else if (this.IsInTransaction && DataExceptionUtilities.IsTimeoutError(sqlException))
        {
            // We're in a transaction and the calling code needs to handle the timeout 
            string message = string.Format("Timeout occured in transaction for '{0}':", sqlCommandName);

            // Raise a Deadlock exception and the calling code will rollback the transaction
            throw new DataDeadlockException(message, sqlException);
        }
        else
        {
            // Something else has gone wrong
            throw sqlException;
        }   
    }

    /// <summary>
    /// get the SqlConnection object owned by this database (already connected to db) 
    /// </summary>
    public SqlConnection Connection
    {
        get {
            // check whether we've got a connection string (from either identity or static initialise)
            if ( _connectionString == null )
            {
                throw new ArgumentNullException( "connectionString", "Connection string not set" );
            }

            if ( _connection != null )
            {
                return _connection;
            }
            else
            {
                _connection = new SqlConnection( _connectionString );
                return _connection;
            }
        }   
    }

    /// <summary>
    /// Return value from executed stored procedure
    /// </summary>
    public SqlInt32 ReturnValue
    {
        get { return _returnValue; }
        set { _returnValue = value; }
    }
}

Database access class:

public class AuthenticationDBCommands
{
    public static SqlCommand GetLoginName()
    {
        System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("GetLoginName");
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add(new SqlParameter("@RETURN_VALUE", System.Data.SqlDbType.Int, 0, System.Data.ParameterDirection.ReturnValue, false, 0, 0, "RETURN_VALUE", System.Data.DataRowVersion.Current, SqlInt32.Null));

        cmd.Parameters.Add(new SqlParameter("@LoginId", SqlDbType.BigInt, 8, ParameterDirection.Input, false, 0, 0, "LoginId", DataRowVersion.Current, SqlInt64.Null));

        cmd.Parameters.Add(new SqlParameter("@LoginName", SqlDbType.VarChar, 50, ParameterDirection.InputOutput,false, 0, 0, "LoginName", DataRowVersion.Current, SqlString.Null));

        return cmd;
    }
}

public class AuthenticationDBContext : DatabaseContextBase
{
    public AuthenticationDBContext() : base()
    {
    } 

    public void GetLoginName(SqlInt64 LoginId, ref SqlString LoginName)
    {
        SqlCommand cmd = AuthenticationDBCommands.GetLoginName();
        cmd.Parameters[1].Value = LoginId;
        cmd.Parameters[2].Value = LoginName;

        base.ExecuteNonQuery(cmd);
        base.ReturnValue = (SqlInt32) cmd.Parameters[0].Value; 
        LoginName = (SqlString)(cmd.Parameters[2].Value); 
    }
}

So when it’s used inside the ASP.NET web client it look like this:

protected string GetLoginName(long loginId)
{
    SqlString loginName = SqlString.Null;

    using (AuthenticationDBContext dbc = new AuthenticationDBContext())
    {
      dbc.GetLoginName(loginId, ref loginName);
    }

    return loginName.Value;
}

As you can see this is fairly standard stuff. But when the AuthenticationDBContext.GetLoginName() method is called by many different users in quick succession the loginName object is sometimes null.

When the SqlCommand.ExecuteNonQuery() fails to return any data it does not throw an exception.

I have tested the SQL and it always finds a value (I’ve inserted @LoginName into a table and it’s never null). So the problem is happening after or in SqlCommand.ExecuteNonQuery();

As I said, this is an example of what it happening. In reality, data is not being returned for lots of different stored procedures.

It’s also worth stating that other web clients that share the app pool in IIS are not affected when the web client in question is under a heavy load.

I’m using .NET 4.5 and my database is on SQL Server 2008.

Has anyone seen anything like this before?
Can anyone recommend any changes?

Thanks in advance,

Matt

UPDATE. Thanks for all your comments. I have made the following change to the DatabaseContextBase class.

                private void ExecuteNonQueryImpl(SqlCommand command)
            {
                object _lockObject = new object();

                lock (_lockObject)
                {
                    SqlConnection con = this.GetConnection();
                    if (con.State != ConnectionState.Open)
                    {
                        con.Open();
                    }

                    // don't need a try catch as this is only ever called from another method in this 
                    // class which will wrap it.
                    command.Connection = con;
                    command.Transaction = _transaction;
                    command.CommandTimeout = _commandTimeout;

                    for (int currentAttempt = 1; currentAttempt <= _maxDatabaseExecuteAttempts; currentAttempt++)
                    {
                        try
                        {
                            // do it
                            command.ExecuteNonQuery();

                            // done, exit loop
                            break;
                        }
                        catch (SqlException sex)
                        {
                            HandleDatabaseExceptions(currentAttempt, sex, command.CommandText);
                        }
                    }

                    if (!this.IsInTransaction)
                    {
                        con.Close();
                    }
                }
            }

            public SqlConnection GetConnection()
            {
                if (this.IsInTransaction)
                {
                    return this.Connection;
                }
                else
                {
                    // check whether we've got a connection string (from either identity or static initialise)
                    if ( _connectionString == null )
                    {
                        string exceptionMessage = Language.Translate("DbContextNotInitialized");

                        throw new ArgumentNullException( "connectionString", exceptionMessage );
                    }

                    return new SqlConnection(_connectionString);
                }
            }

However, in a load test the data still sometimes comes back as null. The web client is not working in a transaction so a new SqlConnection object is created, opened and closed every time a call is made. (there are other areas of code which share the DatabaseContextBase class that do work in a transaction so the original connection property is needed)

I would like to mention that again that I’m confident that the store procedure is working correctly as I have inserted the @LoginName value into a table and it’s never null.

Thanks,
Matt

Code Snippet

public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) {

string username = (string)context[«UserName»];

bool userIsAuthenticated = (bool)context[«IsAuthenticated»];

if (username == null || username.Length < 1 || collection.Count < 1)

return;

SqlConnection conn = null;

SqlDataReader reader = null;

SqlCommand cmd = null;

try {

bool anyItemsToSave = false;

// First make sure we have at least one item to save

foreach (SettingsPropertyValue pp in collection) {

if (pp.IsDirty) {

if (!userIsAuthenticated) {

bool allowAnonymous = (bool)pp.Property.Attributes[«AllowAnonymous»];

if (!allowAnonymous)

continue;

}

anyItemsToSave = true;

break;

}

}

if (!anyItemsToSave)

return;

conn = new SqlConnection(_sqlConnectionString);

conn.Open();

List<ProfileColumnData> columnData = new List<ProfileColumnData>(collection.Count);

foreach (SettingsPropertyValue pp in collection) {

if (!userIsAuthenticated) {

bool allowAnonymous = (bool)pp.Property.Attributes[«AllowAnonymous»];

if (!allowAnonymous)

continue;

}

//Normal logic for original SQL provider

//if (!pp.IsDirty && pp.UsingDefaultValue) // Not fetched from DB and not written to

//Can eliminate unnecessary updates since we are using a table though

if (!pp.IsDirty)

continue;

string persistenceData = pp.Property.Attributes[«CustomProviderData»] as string;

// If we can’t find the table/column info we will ignore this data

if (String.IsNullOrEmpty(persistenceData)) {

// REVIEW: Perhaps we should throw instead?

continue;

}

string[] chunk = persistenceData.Split(new char[] { ‘;’ });

if (chunk.Length != 2) {

// REVIEW: Perhaps we should throw instead?

continue;

}

string columnName = chunk[0];

// REVIEW: Should we ignore case?

SqlDbType datatype = (SqlDbType)Enum.Parse(typeof(SqlDbType), chunk[1], true);

object value = null;

// REVIEW: Is this handling null case correctly?

if (pp.Deserialized && pp.PropertyValue == null) { // is value null?

value = DBNull.Value;

}

else {

value = pp.PropertyValue;

}

// REVIEW: Might be able to ditch datatype

columnData.Add(new ProfileColumnData(columnName, pp, value, datatype));

}

// Figure out userid, if we don’t find a userid, go ahead and create a user in the aspnetUsers table

Guid userId = Guid.Empty;

cmd = new SqlCommand(«SELECT u.UserId FROM vw_aspnet_Users u WHERE u.ApplicationId = ‘» + AppId + «‘ AND u.UserName = LOWER(@Username)», conn);

cmd.CommandType = CommandType.Text;

cmd.Parameters.AddWithValue(«@Username»,username);

try {

reader = cmd.ExecuteReader();

if (reader.Read()) {

userId = reader.GetGuid(0);

}

else {

reader.Close();

cmd.Dispose();

reader = null;

cmd = new SqlCommand(«dbo.aspnet_Users_CreateUser», conn);

cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.AddWithValue(«@ApplicationId», AppId);

cmd.Parameters.AddWithValue(«@UserName», username);

cmd.Parameters.AddWithValue(«@IsUserAnonymous», !userIsAuthenticated);

cmd.Parameters.AddWithValue(«@LastActivityDate», DateTime.UtcNow);

cmd.Parameters.Add(CreateOutputParam(«@UserId», SqlDbType.UniqueIdentifier, 16));

cmd.ExecuteNonQuery();

userId = (Guid)cmd.Parameters[«@userid»].Value;

}

}

finally {

if (reader != null) {

reader.Close();

reader = null;

}

cmd.Dispose();

}

// Figure out if the row already exists in the table and use appropriate SELECT/UPDATE

cmd = new SqlCommand(String.Empty, conn);

StringBuilder sqlCommand = new StringBuilder(«IF EXISTS (SELECT 1 FROM «).Append(_table);

sqlCommand.Append(» WHERE UserId = @UserId) «);

cmd.Parameters.AddWithValue(«@UserId», userId);

// Build up strings used in the query

StringBuilder columnStr = new StringBuilder();

StringBuilder valueStr = new StringBuilder();

StringBuilder setStr = new StringBuilder();

int count = 0;

foreach (ProfileColumnData data in columnData) {

columnStr.Append(«, «);

valueStr.Append(«, «);

columnStr.Append(data.ColumnName);

string valueParam = «@Value» + count;

valueStr.Append(valueParam);

cmd.Parameters.AddWithValue(valueParam, data.Value);

// REVIEW: Can’t update Timestamps?

if (data.DataType != SqlDbType.Timestamp) {

if (count > 0) {

setStr.Append(«,»);

}

setStr.Append(data.ColumnName);

setStr.Append(«=»);

setStr.Append(valueParam);

}

++count;

}

columnStr.Append(«,LastUpdatedDate «);

valueStr.Append(«,@LastUpdatedDate»);

setStr.Append(«,LastUpdatedDate=@LastUpdatedDate»);

cmd.Parameters.AddWithValue(«@LastUpdatedDate», DateTime.UtcNow);

sqlCommand.Append(«BEGIN UPDATE «).Append(_table).Append(» SET «).Append(setStr.ToString());

sqlCommand.Append(» WHERE UserId = ‘»).Append(userId).Append(«‘»);

sqlCommand.Append(«END ELSE BEGIN INSERT «).Append(_table).Append(» (UserId»).Append(columnStr.ToString());

sqlCommand.Append(«) VALUES (‘»).Append(userId).Append(«‘»).Append(valueStr.ToString()).Append(«) END»);

cmd.CommandText = sqlCommand.ToString();

cmd.CommandType = CommandType.Text;

cmd.ExecuteNonQuery(); //THIS cmd.ExecuteNonQuery Produces the Error

// Need to close reader before we try to update

if (reader != null) {

reader.Close();

reader = null;

}

UpdateLastActivityDate(conn, userId);

}

finally {

if (reader != null)

reader.Close();

if (cmd != null)

cmd.Dispose();

if (conn != null)

conn.Close();

}

}

Вам нужно назначить соединение SqlCommand, вы можете использовать конструктор или свойство:

cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ");
cmd.InsertCommand.Connection = connection1;

Я настоятельно рекомендую использовать using-statement для любого типа, реализующего IDisposable как SqlConnection, он также закроет соединение:

using(var connection1 = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=syslog2;Integrated Security=True"))
{
    SqlDataAdapter cmd = new SqlDataAdapter();  
    using(var insertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) "))
    {
        insertCommand.Connection = connection1;
        cmd.InsertCommand = insertCommand;
        //.....
        connection1.Open();
        // .... you don't need to close the connection explicitely
    }
}

Кроме того, вам не нужно создавать новое соединение и DataAdapter для каждой записи в foreach, даже если создание, открытие и закрытие соединения означает не, означает, что ADO.NET создаст, откроет и закроет соединение физическое, но просто заглянет в пул соединений для доступного подключения. Тем не менее это лишние накладные расходы.

The «ExecuteNonQuery requires the command to have a transaction» error occurs in C# when an attempt is made to execute a non-query command, such as an INSERT, UPDATE, or DELETE statement, without having an active transaction. The error message is indicating that the SQL Server requires a transaction to be created before executing a non-query command, as a way to ensure data consistency and integrity.

Method 1: Use Transaction

To fix the «ExecuteNonQuery requires the command to have a transaction» error in C#, you can use the UseTransaction method. This method ensures that the command is executed within a transaction, which is required for ExecuteNonQuery to work properly.

Here’s an example code:

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    SqlTransaction transaction = connection.BeginTransaction();

    try
    {
        SqlCommand command = new SqlCommand(queryString, connection);
        command.Transaction = transaction;

        // Execute the command
        command.ExecuteNonQuery();

        // Commit the transaction
        transaction.Commit();
    }
    catch (Exception ex)
    {
        // Rollback the transaction if an exception occurs
        transaction.Rollback();
        Console.WriteLine("Error: " + ex.Message);
    }
}

In this example, we first open a connection to the database and start a transaction using the BeginTransaction method. We then create a SqlCommand object and set its Transaction property to the transaction we just created. This ensures that the command is executed within the transaction.

We then execute the command using the ExecuteNonQuery method. If an exception occurs, we rollback the transaction using the Rollback method. If the command executes successfully, we commit the transaction using the Commit method.

Using the UseTransaction method ensures that the command is executed within a transaction, which is required for ExecuteNonQuery to work properly.

Method 2: Use BeginTransaction Method

To fix the «ExecuteNonQuery requires the command to have a transaction» error in C#, you can use the BeginTransaction method. This method allows you to group multiple database operations into a single transaction, which ensures that either all operations are executed successfully or none of them are.

Here’s an example code snippet that shows how to use BeginTransaction:

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    SqlTransaction transaction = connection.BeginTransaction();

    try
    {
        SqlCommand command1 = new SqlCommand("INSERT INTO Table1 (Column1) VALUES ('Value1')", connection, transaction);
        command1.ExecuteNonQuery();

        SqlCommand command2 = new SqlCommand("INSERT INTO Table2 (Column1) VALUES ('Value2')", connection, transaction);
        command2.ExecuteNonQuery();

        transaction.Commit();
    }
    catch (Exception ex)
    {
        transaction.Rollback();
        Console.WriteLine("Error: " + ex.Message);
    }
}

In this example, we first open a connection to the database using the SqlConnection class. We then create a new transaction using the BeginTransaction method and associate it with the connection.

Next, we create two SqlCommand objects that insert data into two different tables. We pass the transaction object to each command so that they are included in the same transaction.

If both commands execute successfully, we commit the transaction using the Commit method. If an error occurs during the transaction, we roll back the transaction using the Rollback method.

Note that we wrap the entire code block in a try-catch statement to handle any exceptions that may occur during the transaction.

Using the BeginTransaction method is a simple and effective way to group multiple database operations into a single transaction and avoid the «ExecuteNonQuery requires the command to have a transaction» error in C#.

Method 3: Use BeginTransaction Method with IsolationLevel

To fix the «ExecuteNonQuery requires the command to have a transaction» error in C#, you can use the BeginTransaction method with IsolationLevel. Here’s how to do it:

  1. Create a new SqlConnection object and open the connection:
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    // your code here
}
  1. Create a new SqlTransaction object using the BeginTransaction method with the desired IsolationLevel:
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    SqlTransaction transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
    // your code here
}
  1. Create a new SqlCommand object and assign the SqlTransaction object to its Transaction property:
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    SqlTransaction transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
    SqlCommand cmd = new SqlCommand(sql, conn);
    cmd.Transaction = transaction;
    // your code here
}
  1. Execute the command using the ExecuteNonQuery method:
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    SqlTransaction transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
    SqlCommand cmd = new SqlCommand(sql, conn);
    cmd.Transaction = transaction;
    int rowsAffected = cmd.ExecuteNonQuery();
    // your code here
}
  1. Commit the transaction using the Commit method:
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    SqlTransaction transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
    SqlCommand cmd = new SqlCommand(sql, conn);
    cmd.Transaction = transaction;
    int rowsAffected = cmd.ExecuteNonQuery();
    transaction.Commit();
}
  1. If an error occurs, rollback the transaction using the Rollback method:
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    SqlTransaction transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
    try
    {
        SqlCommand cmd = new SqlCommand(sql, conn);
        cmd.Transaction = transaction;
        int rowsAffected = cmd.ExecuteNonQuery();
        transaction.Commit();
    }
    catch (Exception ex)
    {
        transaction.Rollback();
        throw ex;
    }
}

That’s it! By using the BeginTransaction method with IsolationLevel, you can fix the «ExecuteNonQuery requires the command to have a transaction» error in your C# code.

Method 4: Use using Statement with TransactionScope

To fix the «ExecuteNonQuery requires the command to have a transaction» error in your C# code, you can use the TransactionScope class along with the using statement. This allows you to create a transaction scope that will automatically handle the transaction for you, including committing or rolling back the transaction as necessary.

Here is an example of how to use the TransactionScope class with the using statement:

using (TransactionScope scope = new TransactionScope())
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        
        SqlCommand command1 = new SqlCommand("INSERT INTO table1 (column1) VALUES (@value1)", connection);
        command1.Parameters.AddWithValue("@value1", "example value");
        command1.ExecuteNonQuery();
        
        SqlCommand command2 = new SqlCommand("INSERT INTO table2 (column2) VALUES (@value2)", connection);
        command2.Parameters.AddWithValue("@value2", "another example value");
        command2.ExecuteNonQuery();
    }
    
    scope.Complete();
}

In this example, we first create a new TransactionScope object using the using statement. Inside the scope, we create a new SqlConnection object and open the connection to the database.

We then create two SqlCommand objects to insert data into two different tables. We use the AddWithValue method to add parameterized values to the commands, which helps prevent SQL injection attacks.

Finally, we call the ExecuteNonQuery method on each command to execute the SQL statements and insert the data into the tables.

After the SQL commands have been executed, we call the Complete method on the TransactionScope object to commit the transaction. If an exception occurs before this point, the transaction will automatically be rolled back.

Using the TransactionScope class with the using statement is a simple and effective way to handle transactions in your C# code and avoid the «ExecuteNonQuery requires the command to have a transaction» error.

Понравилась статья? Поделить с друзьями:

Интересное по теме:

  • Commandos ошибка инициализации
  • Contract wars ошибка входа неизвестная причина
  • Confluence установить ошибку шага
  • Comctl32 dll ошибка при запуске windows 7
  • Command conquer generals zero hour ошибка при запуске

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии