DataARTIGO

Como exibir informações com múltiplas instruções SQL

Ao utilizar múltiplas instruções SQL, economizamos os recursos compartilhados da rede e servidor, como largura de banda, memória e CPU, pois reduzimos o número de acessos ao servidor web.

Neste artigo veremos como retornar registros com uma stored procedure com duas instruções SQL.

Inicialmente, declaramos a string de conexão com o banco de dados

string strConexao = "Data Source=(local);Integrated Security=SSPI;Initial Catalog=Northwind;";

e a stored procedure usada no exemplo:

string sSql = "GetTotalAndProdutos";

Se preferir, utilize instruções SQL separadas por ponto-e-vírgula:

string sSql = " SELECT Count(*) AS Total FROM Products; SELECT ProductName, UnitPrice FROM Products"; 

Com a instrução using criamos uma nova instância da classe SqlConnection e passamos a string de conexão:

using (SqlConnection conn = new SqlConnection(strConexao))
{

Criamos e definimos um objeto SqlDataReader como null.

SqlDataReader r = null;

Em seguida, criamos uma nova instância da classe SqlCommand e passamos ao construtor o objeto SqlConnection e a string com o nome da stored procedure.

SqlCommand cmd = new SqlCommand(sSql, conn);

Definimos a propriedade CommandType como StoredProcedure.

cmd.CommandType = CommandType.StoredProcedure;

Ao usar instruções SQL, defina a propriedade CommandType como Text:

cmd.CommandType = CommandType.Text;

Dentro dos blocos try, catch, finally, respectivamente, abrimos e exibimos os dados, manipulamos as exceções que podem ocorrer e fechamos a conexão com o banco de dados.

try
{
	conn.Open();

Definimos o objeto SqlDataReader:

r = cmd.ExecuteReader(CommandBehavior.CloseConnection);

Retornamos o índice do campo “total”:

int t = r.GetOrdinal("total");

Exibimos a string “Total de registros:”.

Response.Write("<b><span style=\"text-decoration: underline\">Total de registros:</span></b> ");

Iniciamos a leitura dos dados:

r.Read();

e exibimos o total de registros retornados:

Response.Write(r.GetInt32(t) + "<br/>");

Usamos o método NextResult para exibir os registros do próximo conjunto de registros:

r.NextResult();

Verificamos se há registros para exibir:

if (r.HasRows)

Neste caso especifico, podemos usar também:

if (r.GetInt32(t) > 0)

Em seguida, extraímos o índice do campo ProductName e do campo UnitPrice.

int produto = r.GetOrdinal("ProductName");
int valor = r.GetOrdinal("UnitPrice");

Criamos a tabela onde exibiremos os dados.

Response.Write("<table><tr><td style=\"width: 150px\"><b>Produto</b></td><td style=\"width: 100px\"><b>Valor unitário</b></td></tr>");

Percorremos todos os registros do segundo conjunto de registros.

while (r.Read())
{

Exibimos o nome do produto com o método GetString:

Response.Write("<tr><td style=\"width: 150px\">" + r.GetString(produto) + "</td>");

e o valor unitário de cada produto com o método GetDecimal:

Response.Write("<td style=\"width: 100px\">" + string.Format(ci,"{0:c}", r.GetDecimal(valor)) + "</td></tr>");

O método Format da classe String formata a saída como um valor monetário

string.Format(ci,"{0:c}", r.GetDecimal(valor))

e define a cultura como pt-BR – Português Brasil. Desta forma, a saída será sempre em reais, independente do idioma usado pelo computador do usuário.

CultureInfo ci = new CultureInfo("pt-BR");

Ao finalizar o exemplo, exibimos a tag de fechamento da tabela:

Response.Write("</table>");

exibimos o bloco catch

catch (SqlException)
{
	Response.Write("Erro SQL.");
}

e o bloco finally, onde encerramos a conexão com o banco de dados.

finally
{
	if (!r.IsClosed) r.Close();
}

A seguir, temos os arquivos e códigos que compõe este exemplo.

//Arquivo de exemplo: Default.aspx.cs
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string strConexao = "Data Source=(local);Integrated Security=SSPI;Initial Catalog=Northwind;";
        string sSql = "GetTotalAndProdutos";
        using (SqlConnection conn = new SqlConnection(strConexao))
        {
            SqlDataReader r = null;
            SqlCommand cmd = new SqlCommand(sSql, conn);
            cmd.CommandType = CommandType.Text;

            try
            {
                conn.Open();
                r = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                int t = r.GetOrdinal("total");
                Response.Write("<b><span style=\"text-decoration: underline\">Total de registros:</span></b> ");
                r.Read();
                Response.Write(r.GetInt32(t) + "<br/>");

                r.NextResult();
                if (r.HasRows)
                {
                    int produto = r.GetOrdinal("ProductName");
                    int valor = r.GetOrdinal("UnitPrice");
                    Response.Write("<table><tr><td style=\"width: 150px\"><b>Produto</b></td><td style=\"width: 100px\"><b>Valor unitário</b></td></tr>");

                    CultureInfo ci = new CultureInfo("pt-BR");
                    while (r.Read())
                    {
                        Response.Write("<tr><td style=\"width: 150px\">" + r.GetString(produto) + "</td>");
                        Response.Write("<td style=\"width: 100px\">" + string.Format(ci,"{0:c}", r.GetDecimal(valor)) + "</td></tr>");
                    }
                    Response.Write("</table>");
                }
            }
            catch (SqlException)
            {
                Response.Write("Erro SQL.");
            }            
            finally
            {
                if (!r.IsClosed) r.Close();
            }
        }
    }
}

Temos o arquivo Default.aspx

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html>
<head runat="server">
    <title>Exemplo com o método NextResult</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
        </div> 
    </form>
</body>
</html>
 e a stored procedure [cor2]GetTotalAndProdutos [/cor2] usada no exemplo:
CREATE PROCEDURE GetTotalAndProdutos 
AS
SET NOCOUNT ON
SELECT Count(*) AS Total FROM Products
SELECT     ProductName, UnitPrice FROM Products
GO

é autor dos livros "XML para programadores ASP" e "ASP.NET com C#: curso prático", pela editora Novatec. Também é editor do Asprs.net.

Ver perfil