Recentemente no trabalho, meu amigo Cícero estava precisando elaborar um relatório para impressão de etiquetas. Até aí tudo bem, tarefa trivial para quem sabe fazer relatórios complexos como é o caso do Cícero.
A coisa só complicou porque era para imprimir apenas um item por "n" vezes. Ou seja, o usuário iria selecionar um produto e informar o número de etiquetas que seriam impressas para este item.
Geralmente, no trabalho, a ideia é resolver tudo com uma SQL que retorne um rowset e ponto final. Você faz o databound no relatório e zero código precisa ser escrito no corpo do relatório já que o engine e de um fabricante muito usado.
O problema era: como gerar um conjunto de linhas com uma consulta SQL (de preferência do jeito preguiçoso)?
Se você quiser, por outro lado, fazer isso do jeito difícil, outros artigos abaixo:
A primeira parte são criadas as variáveis necessárias. O resultado segue abaixo.
E funciona? Quer dizer, em um programa?
Sim, o código abaixo (que não vou explicar agora... estou com preguiça...) demonstra a utilização da consulta acima em um programa Windows Forms.
A coisa só complicou porque era para imprimir apenas um item por "n" vezes. Ou seja, o usuário iria selecionar um produto e informar o número de etiquetas que seriam impressas para este item.
Geralmente, no trabalho, a ideia é resolver tudo com uma SQL que retorne um rowset e ponto final. Você faz o databound no relatório e zero código precisa ser escrito no corpo do relatório já que o engine e de um fabricante muito usado.
O problema era: como gerar um conjunto de linhas com uma consulta SQL (de preferência do jeito preguiçoso)?
Conceitos envolvidos
Se você estiver querendo dar aula ou entender mais profundamente os conceitos, eis aqui a lista e os links para a documentação oficial:Se você quiser, por outro lado, fazer isso do jeito difícil, outros artigos abaixo:
- Repeating a SQL row based on a value in a different column
- SQL Repeat Rows N Times According to Column Value
1. Foi usada uma variável para ser incrementada pelo número de repetições desejado.
declare @repeat as int=0; declare @temp as table (name varchar(50));
2. Foi criado um loop que preenche uma tabela temporário (usando uma table variable) pelo número de vezes desejado.
while @repeat < 10
begin
insert into @temp select name from Production.product where name = 'blade';
set @repeat=@repeat+1;
end
3. Ao término do loop, foi enviada uma consulta SELECT para a tabela temporária que traz os resultados desejados.
select * from @temp
No exemplo, eu demonstrei como repetir a coluna Name da tabela Production.Products do banco de dados AdventureWorks2012 da Microsoft. A primeira parte são criadas as variáveis necessárias. O resultado segue abaixo.
E funciona? Quer dizer, em um programa?
Sim, o código abaixo (que não vou explicar agora... estou com preguiça...) demonstra a utilização da consulta acima em um programa Windows Forms.
void Main() { // SQL Server Repeat Rows generateForm(); } // Define other methods and classes here void generateForm() { var frm = new System.Windows.Forms.Form { Width = 300, Height = 300, Text = "Exemplo" }; var lst = new System.Windows.Forms.ListBox { Dock = System.Windows.Forms.DockStyle.Fill }; frm.Controls.Add(lst); getRows(lst); frm.ShowDialog(); } void getRows(System.Windows.Forms.ListBox lst) { lst.DataSource = getDataRows(); } ListgetDataRows() { using(var con = new SqlConnection(@"Data source=.\sqlexpress; initial catalog=AdventureWorks2012; Integrated security=true")) { using(var cmd = new SqlCommand("", con)) { cmd.CommandText = @" declare @repeat as int=0; declare @temp as table (name varchar(50)); while @repeat < 10 begin insert into @temp select name from Production.product where name = 'blade'; set @repeat=@repeat+1; end; select * from @temp; "; con.Open(); var reader = cmd.ExecuteReader(); var lst = new List (); while (reader.Read()) { lst.Add(reader["name"].ToString()); } con.Close(); return lst; } } }