Neste artigo, veremos como incorporar parâmetros aos comandos SqlCommand com o C#, além de verificar as técnicas que fazem uso e designam parâmetros para seus comandos, incluindo benefícios como transformar o seu código em um código mais seguro.

A partir de agora, veremos diversos tópicos, tais como as explicações sobre os parâmetros, os benefícios de se usar parâmetros, aprender como se usa e cria um parâmetro e, finalmente, aprender como adicionar parâmetros aos comandos.

Introdução ao SqlCommand e parâmetros

Quando estamos trabalhando com dados, sempre vemos a necessidade de filtrar os resultados baseados em cláusulas where. Geralmente, isto é obtido pela entrada de dados de um usuário e fazendo uso dessa entrada de dados para formar a query. Para exemplificar esta situação, podemos ter um vendedor que está à procura de todos os pedidos feitos entre datas específicas. A outra query poderia incluir um recurso de filtragem de clientes por bairro.

Todos estão cientes de que uma query designada a um SqlCommand é simplesmente uma string, assim se alguém é solicitado a filtrar os dados de uma query, essa pessoa poderia criar uma string dinamicamente. Entretanto, ninguém iria querer fazer isto, e o exemplo abaixo exemplifica muito bem essa situação, de um péssimo exemplo ao se filtrar uma query.

Listagem 1: Mau exemplo de filtragem de query


// forma não indicada de ser fazer
SqlCommand cmd = new SqlCommand(
"select * from CLIENTES where BAIRRO = '" + _bairro + "'";

Ninguém nunca deve criar uma query desta maneira. A variável de entrada, _bairro, é normalmente extraída de um TextBox control. Isto pode ser feito tanto em um Windows form quanto em uma Página Web. Qualquer coisa que se entre em um TextBox control irá para o _bairro e, daí será adicionado a sua string do SQL. Nesta situação, se está basicamente convidando um hacker a substituir a string por algo malicioso. Alguém poderia ter acesso completo ao computador no pior dos cenários.

O que deve ser feito é se usar os parâmetros ao invés de dinamicamente construir uma string como foi demonstrado no exemplo acima.

Qualquer texto que se entre em um parâmetro será tratado como uma informação de campo. Isto não é considerado uma parte do SQL statement e torna a sua aplicação muito mais segura.

Um processo de três passos para se fazer uso de queries com parâmetros é construir a string de comando no SqlCommand com parâmetros, declarar um objeto de SqlParameter, passando valores apropriados e designar o objeto SqlParameter as propriedades do objeto do SqlCommand. Será apresentado tudo isso em um processo passo-a-passo a seguir.

Conseguindo um objeto do tipo SqlCommand

O primeiro grande passo para se fazer uso dos parâmetros nas queries do SQL é construir uma string de comando que possa abranger os locais de parâmetros. Quando o SqlCommand tem seu funcionamento ativado, estes locais são preenchidos com valores de parâmetros de verdade. As listas abaixo mostram a sintaxe do parâmetro, que se deve usar um prefixo arroba "@" antes do nome do parâmetro.

Listagem 2: Sintaxe do parâmetro


// Criando o SqlCommand com um parâmetro
SqlCommand cmd = new SqlCommand(
"select * from CLIENTES where BAIRRO = @Bairro ", conn);

Tem-se um primeiro argumento contendo uma declaração de parâmetro, @Bairro no comando SQL acima mencionado. Apenas um parâmetro é usado no exemplo, no entanto tantos quantos parâmetros podem ser usados para se customizar a query. Cada um dos parâmetros irá se combinar com o objeto SqlParameter. Isto deve ser designado a este objeto SqlCommand.

Declarando um objeto do tipo SqlParameter

Cada um dos parâmetros no SQL statement deve ser definido apropriadamente. O código deve declarar um tipo SqlParameter e o código deve definir uma instância de SqlParameter para cada parâmetro na lista de objetos da SQL command de uma SqlCommand. O código abaixo reflete o parâmetro para o @City parâmetro:

Listagem 3: Utilizando o @Bairro

// Criando os parâmetros utilizados na consulta 
SqlParameter param  = new SqlParameter();    
param.ParameterName = "@Bairro";    
param.Value         = inputCity;

O programador deve manter em mente que as formas de escrita da propriedade ParameterName da instância do SqlParameter devem ser as mesmas que os parâmetros que são usados na string do SqlCommand. Assim como, deve-se definir um valor para o comando e quando o objeto do SqlCommand é implementado ou posto para funcionar, este valor será substituído pelo parâmetro.

Juntando Tudo

Já estamos cientes sobre o processo de uso do SqlCommand e dos objetos do SqlDataReader. O código abaixo irá ilustrar um programa em funcionamento que se utiliza dos objetos do SqlParameter. Então, o programador deve se adaptar agora a todos estes pontos e a lista abaixo apresenta o código para adicionar parâmetros às queries.

Listagem 4: Adicionando Parâmetros ás Queries

using System;
using System.Data;
using System.Data.SqlClient;
 
class ParamDemo
{
    static void Main()
    {
        // conn and reader declared outside try
        // block for visibility in finally block
        SqlConnection conn   = null;
        SqlDataReader reader = null;
 
        string inputCity = "São Paulo";
 
        try
        {
            // instantiate and open connection
            conn =  new
                SqlConnection("Server=(local);DataBase=MeuBanco;Integrated Security=SSPI");
            conn.Open();
 
            // don't ever do this
            // SqlCommand cmd = new SqlCommand(
            // "select * from CLIENTES where BAIRRO = '" + _bairro + "'";
 
            // Criando o SqlCommand com parâmetro
            SqlCommand cmd = new SqlCommand(
                "select * from CLIENTES where BAIRRO = @Bairro ", conn);
 
            // Define as informações do parâmetro criado
            SqlParameter param  = new SqlParameter();
            param.ParameterName = "@Bairro";
            param.Value = _bairro;
 
            // Inserindo o parâmetro no comando
            cmd.Parameters.Add(param);
 
            // Executando o commando e obtendo o resultado
            reader = cmd.ExecuteReader();
 
            // Exibindo os registros
            while(reader.Read())
            {
                Console.WriteLine("{0}, {1}", 
                    reader["Nome"], 
                    reader["Email"]);
            }
        }
        finally
        {
            // Fecha o datareader
            if (reader != null)
            {
                reader.Close();
            }
 
            // Fecha a conexão
            if (conn != null)
            {
                conn.Close();
            }
        }
    }
}

Com o código acima na Listagem 4 podemos tranquilamente consultar os registros para cada cliente que mora em um determinado bairro, sem medo de sofrer injeção de SQL. Isto é feito de maneira mais segura através de parâmetros de assistência.

Conclusão

Aprendeu-se neste artigo que é necessário fazer uso de parâmetros para filtrar queries em um modo muito mais seguro. Este processo de utilizar parâmetros possui três passos, que são: definir os parâmetros numa string de comando no SqlCommand, declarar o objeto do tipo SqlParameter com as propriedades aplicáveis e designar ao objeto do tipo SqlParameter um objeto do tipo SqlCommand.

Isto é tudo por hoje, espero que vocês tenham gostado do artigo, e espero também vê-los em breve.