Modificar dados com procedimentos armazenados
Aplicável a: .NET Framework .NET .NET Standard
Os procedimentos armazenados podem aceitar dados como parâmetros de entrada e podem retornar dados como parâmetros de saída, conjuntos de resultados ou valores de retorno. O exemplo abaixo ilustra como o Provedor de Dados do Microsoft SqlClient para o SQL Server envia e recebe parâmetros de entrada, parâmetros de saída e valores retornados. O exemplo insere um novo registro em uma tabela, em que a coluna de chave primária é uma coluna de identidade.
Observação
Se você estiver usando procedimentos armazenados para editar ou excluir dados por meio de um SqlDataAdapter, não use SET NOCOUNT ON na definição do procedimento armazenado. Isso faz com que a contagem retornada de linhas afetadas seja zero, o que o DataAdapter
interpreta como um conflito de simultaneidade. Nesse caso, será gerada uma DBConcurrencyException.
Exemplo
O exemplo usa o procedimento armazenado a seguir para inserir uma nova categoria na tabela Northwind Categories. O procedimento armazenado usa o valor da coluna CategoryName como um parâmetro de entrada e a função SCOPE_IDENTITY() para recuperar o novo valor do campo de identidade, CategoryID, e retorná-lo em um parâmetro de saída. A instrução RETURN usa a função @@ROWCOUNT para retornar o número de linhas inseridas.
CREATE PROCEDURE dbo.InsertCategory
@CategoryName nvarchar(15),
@Identity int OUT
AS
INSERT INTO Categories (CategoryName) VALUES(@CategoryName)
SET @Identity = SCOPE_IDENTITY()
RETURN @@ROWCOUNT
O código de exemplo a seguir usa o procedimento armazenado InsertCategory
mostrado acima como a origem de InsertCommand de SqlDataAdapter. O parâmetro de saída @Identity
será refletido em DataSet após a inserção do registro no banco de dados quando o método Update
de SqlDataAdapter for chamado. O código também recupera o valor de retorno.
using System;
using System.Data;
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
ReturnIdentity(connectionString);
// Console.ReadLine();
}
private static void ReturnIdentity(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create a SqlDataAdapter based on a SELECT query.
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT CategoryID, CategoryName FROM dbo.Categories", connection);
// Create a SqlCommand to execute the stored procedure.
adapter.InsertCommand = new SqlCommand("InsertCategory", connection);
adapter.InsertCommand.CommandType = CommandType.StoredProcedure;
// Create a parameter for the ReturnValue.
SqlParameter parameter = adapter.InsertCommand.Parameters.Add("@RowCount", SqlDbType.Int);
parameter.Direction = ParameterDirection.ReturnValue;
// Create an input parameter for the CategoryName.
// You do not need to specify direction for input parameters.
adapter.InsertCommand.Parameters.Add("@CategoryName", SqlDbType.NChar, 15, "CategoryName");
// Create an output parameter for the new identity value.
parameter = adapter.InsertCommand.Parameters.Add("@Identity", SqlDbType.Int, 0, "CategoryID");
parameter.Direction = ParameterDirection.Output;
// Create a DataTable and fill it.
DataTable categories = new DataTable();
adapter.Fill(categories);
// Add a new row.
DataRow categoryRow = categories.NewRow();
categoryRow["CategoryName"] = "New Beverages";
categories.Rows.Add(categoryRow);
// Update the database.
adapter.Update(categories);
// Retrieve the ReturnValue.
Int rowCount = (Int)adapter.InsertCommand.Parameters["@RowCount"].Value;
Console.WriteLine("ReturnValue: {0}", rowCount.ToString());
Console.WriteLine("All Rows:");
foreach (DataRow row in categories.Rows)
{
Console.WriteLine(" {0}: {1}", row[0], row[1]);
}
}
}
static private string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=(local);Initial Catalog=Northwind;Integrated Security=true";
}
}