Pregunta

Browsed some answers and doesn't appear to be working for me.

I need the ID field of a table to be returned so I can use it in a different part of the program, I've tried using

    Convert.ToInt32(sqlComm.ExecuteScalar());

But no luck, and same for

    Convert.ToInt32(sqlComm.Parameters["ID"].Value);

And both return 0, even though the record does get inserted into the table.

I'll dump the code below, can anyone see what I'm doing wrong?

    using (SqlConnection sqlConnect = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
        {
            using (SqlCommand sqlComm = new SqlCommand("up_Insert_Address", sqlConnect))
            {
                sqlComm.CommandType = CommandType.StoredProcedure;
                sqlComm.Parameters.Add("@AddressID", SqlDbType.BigInt).Direction = ParameterDirection.Output;
                sqlComm.Parameters.Add("@AddressLineOne", SqlDbType.NVarChar, 40).Value = address.AddressLineOne;   

                try
                {
                    sqlComm.Connection.Open();
                    return Convert.ToInt32(sqlComm.ExecuteScalar());
                }

                catch (SqlException)
                {
                }

                finally
                {
                    sqlComm.Connection.Close();
                }
            }
        }

And Stored Procedure:

    @AddressID   Bigint OUTPUT,
    @AddressLineOne  NVarChar(40)
    AS
     BEGIN
      BEGIN TRY
      INSERT INTO Address
      (
         AddressLineOne
      )
      VALUES 
      (
         @AddressLineOne
      )

      SET @AddressID = SCOPE_IDENTITY();
    END TRY
    BEGIN CATCH
       DECLARE @Err nvarchar(500)
       SET @Err = ERROR_MESSAGE()
       RAISERROR(@Err, 16, 1)
    END CATCH
   END
¿Fue útil?

Solución

You should be using

Convert.ToInt64(sqlComm.Parameters["@AddressID"].Value);

after you execute the command using ExceuteNonQuery. For future reference, ExecuteScalar returns the first column of the first row in the result set returned by the query. You're not returning anything, just setting the value of an OUTPUT parameter.

Also you should DEFINITELY not swallow any SqlException. Since your command and connection are already in using blocks you don't need to add another try/catch/finally. Change it to to:

//try
//{
    sqlComm.Connection.Open();
    sqlComm.ExecuteNonQuery();
    return Convert.ToInt64(sqlComm.Parameters["@AddressID"].Value);
    // using Int64 since the SQL type is BigInt
//}

//catch (SqlException)
//{
//}

//finally
//{
//    sqlComm.Connection.Close();
//}

Otros consejos

var connectionstring = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

var addressId = 0L; // long value (64bit)

using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand("up_Insert_Address", connection))
{
  command.CommandType = CommandType.StoredProcedure;

  command.Parameters.AddWithValue("@AddressID", addressId);    
  command.Parameters.AddWithValue("@AddressLineOne", address.AddressLineOne); 

  command.Parameters["@AddressID"].Direction = ParameterDirection.Output;

  try
  {
    if(connection.State != ConnectionState.Open)
      connection.Open();

    var rowsAffected = command.ExecuteNonQuery();
    addressId = Convert.ToInt64(command.Parameters["@AddressID"].Value);
  }
  catch (SqlException)
  {
    // Handle SQL errors here.
  }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top