Desenvolvimento - C#
Como exibir informações com múltiplas instruções SQL
Este artigo mostra como exibir informações com múltiplas instruções SQL por intermédio do método NextResult da classe SqlDataReader.
por Alfredo LotarAo utilizar múltiplas instruções SQL economizamos os recursos compartilhados da rede e servidor, como largura de banda, memória, 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 GetTotalAndProdutos usada no exemplo:
CREATE PROCEDURE GetTotalAndProdutos
AS
SET NOCOUNT ON
SELECT Count(*) AS Total FROM Products
SELECT ProductName, UnitPrice FROM Products
GO