Usuário com melhor resposta
Utilização de vetores ( arrays ) em T-SQL para execução de outras procedures

Pergunta
-
Olá comunidade, peço ajuda pra desenvolver uma rotina muito importante em meu trabalho. Como não sei fazer em t-sql, vou apresentar um código em like VB.NET e gostaria obter uma "tradução" do mesmo em T-SQL. Eis o código:
Dim meses() as string = {"jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"}
Dim anos() as integer = {2007,2008,2009,2010,2011,2012,2013,2014,2015}
Dim relatorios() as string = {"A","B","C","D"}
Dim ano as integer
Dim mes, relatorio as string
FOR EACH relatorio IN relatorios
FOR EACH ano IN anos
FOR EACH mes IN meses
<< EXEC GET_INDICADOR @mes, @ano, @relatorio >>NEXT
NEXT
Pergunta 1 - Como faço para construir esses vetores [e indexá-los através de loops] em procedures T-SQL.
Pergunta 2 - Essa construção pode e/ou gera algum efeito colateral no banco de dados e/ou SGBD, tipo algum erro ou falha?
Pergunto isso, porque acho esse código dentro da procedure GET_INDICADOR, ou seja, quero fazer várias chamadas recursivas.ps: Estou utilizando o SQL Server 2005 Express Edition e não posso receber esses vetores da aplicação.
Tem que ser feitos dentro da própria procedures. Agradeço pela atenção e fico no aguardo online. Att.
Respostas
-
Boa tarde Newton dá uma olhada no exemplo, creio que seja isso
Set
Nocount OnDeclare
@vet_meses Table(Codigo_Mes int identity(1,1),nome char(3))Declare
@vet_anos Table(Ano int)Declare
@vet_relatorios Table(Codigo_Relatorio int identity(1,1),Nome char(1))Insert
into @vet_meses values ('Jan')Insert
into @vet_meses values ('Fev')Insert
into @vet_meses values ('Mar')Insert
into @vet_meses values ('abr')Insert
into @vet_meses values ('Mai')Insert
into @vet_meses values ('Jun')Insert
into @vet_meses values ('Jul')Insert
into @vet_meses values ('Ago')Insert
into @vet_meses values ('Set')Insert
into @vet_meses values ('Out')Insert
into @vet_meses values ('Nov')Insert
into @vet_meses values ('Dez')Insert
into @vet_anos values (2007)Insert
into @vet_anos values (2008)Insert
into @vet_anos values (2009)Insert
into @vet_anos values (2010)Insert
into @vet_anos values (2011)Insert
into @vet_anos values (2012)Insert
into @vet_anos values (2013)Insert
into @vet_anos values (2014)Insert
into @vet_anos values (2015)Insert
into @vet_relatorios values ('A')Insert
into @vet_relatorios values ('B')Insert
into @vet_relatorios values ('C')Insert
into @vet_relatorios values ('D')Declare
@int_RelatorioIni
int,@int_RelatorioFim
int,@int_AnoIni
int,@int_AnoFim
int,@int_MesIni
int,@int_MesFim
int,@str_Ano
varchar(4),@str_Mes
varchar(3),@str_Relatorio
varchar(10)Select
@int_RelatorioIni = Min(Codigo_Relatorio),@int_RelatorioFim = Max(Codigo_Relatorio) From @vet_RelatoriosSelect
@int_AnoIni = Min(Ano),@int_AnoFim = Max(Ano) From @vet_anosSelect
@int_MesIni = Min(Codigo_Mes),@int_MesFim = Max(Codigo_Mes) From @vet_mesesWhile
@int_RelatorioINI <= @int_RelatorioFimBegin
Select @str_Relatorio = Nome From @vet_Relatorios where Codigo_Relatorio = @int_RelatorioINI While @int_AnoINI <= @int_AnoFim Begin Select @str_ano = Ano From @vet_anos where Ano = @int_AnoINI While @int_MesINI <= @int_MesFIM Begin Select @str_Mes = Nome From @vet_meses where Codigo_Mes = @int_MesINI Print 'Exec ' + @str_ano + ' ' + @str_Mes + ' ' + @str_Relatorio Set @int_MesINI = @int_MesINI + 1 End Set @int_AnoINI = @int_AnoINI + 1 End Set @int_RelatorioINI = @int_RelatorioINI + 1End
Espero ter ajudado
Todas as Respostas
-
Olá,
Se fosse no 2000 teríamos um sensível trabalho, mas no 2005 é fácil fácil. Dê uma olhada no código abaixo. É o pontapé para fazer o que você precisa.
Code SnippetDECLARE
@StringDaAplicacao VARCHAR(1000)SET
@StringDaAplicacao = '"jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"'DECLARE
@xml XML, @Var VARCHAR(1000)-- Retirar as aspas duplas e espaços
SET
@Var = REPLACE(@StringDaAplicacao,'"','')SET
@Var = REPLACE(@Var,' ','')-- Substituir o separador por uma tag
SET
@Var = REPLACE(@Var,',','</i><i>')-- Colocar as tags iniciais
SET
@Var = '<e><i>' + @Var + '</i></e>'-- Converte para XML
SET
@xml = CAST(@Var AS XML)-- Retorna os valores em formato tabular
SELECT
t.c.value('.','char(3)')FROM
@xml.nodes('/e/i') T(c)Agora que resolvemos o problema do Array, tem mais alguma pendência que você esteja com dificuldade em relação a essa Thread ?
[ ]s,
Gustavo
-
Boa tarde Newton dá uma olhada no exemplo, creio que seja isso
Set
Nocount OnDeclare
@vet_meses Table(Codigo_Mes int identity(1,1),nome char(3))Declare
@vet_anos Table(Ano int)Declare
@vet_relatorios Table(Codigo_Relatorio int identity(1,1),Nome char(1))Insert
into @vet_meses values ('Jan')Insert
into @vet_meses values ('Fev')Insert
into @vet_meses values ('Mar')Insert
into @vet_meses values ('abr')Insert
into @vet_meses values ('Mai')Insert
into @vet_meses values ('Jun')Insert
into @vet_meses values ('Jul')Insert
into @vet_meses values ('Ago')Insert
into @vet_meses values ('Set')Insert
into @vet_meses values ('Out')Insert
into @vet_meses values ('Nov')Insert
into @vet_meses values ('Dez')Insert
into @vet_anos values (2007)Insert
into @vet_anos values (2008)Insert
into @vet_anos values (2009)Insert
into @vet_anos values (2010)Insert
into @vet_anos values (2011)Insert
into @vet_anos values (2012)Insert
into @vet_anos values (2013)Insert
into @vet_anos values (2014)Insert
into @vet_anos values (2015)Insert
into @vet_relatorios values ('A')Insert
into @vet_relatorios values ('B')Insert
into @vet_relatorios values ('C')Insert
into @vet_relatorios values ('D')Declare
@int_RelatorioIni
int,@int_RelatorioFim
int,@int_AnoIni
int,@int_AnoFim
int,@int_MesIni
int,@int_MesFim
int,@str_Ano
varchar(4),@str_Mes
varchar(3),@str_Relatorio
varchar(10)Select
@int_RelatorioIni = Min(Codigo_Relatorio),@int_RelatorioFim = Max(Codigo_Relatorio) From @vet_RelatoriosSelect
@int_AnoIni = Min(Ano),@int_AnoFim = Max(Ano) From @vet_anosSelect
@int_MesIni = Min(Codigo_Mes),@int_MesFim = Max(Codigo_Mes) From @vet_mesesWhile
@int_RelatorioINI <= @int_RelatorioFimBegin
Select @str_Relatorio = Nome From @vet_Relatorios where Codigo_Relatorio = @int_RelatorioINI While @int_AnoINI <= @int_AnoFim Begin Select @str_ano = Ano From @vet_anos where Ano = @int_AnoINI While @int_MesINI <= @int_MesFIM Begin Select @str_Mes = Nome From @vet_meses where Codigo_Mes = @int_MesINI Print 'Exec ' + @str_ano + ' ' + @str_Mes + ' ' + @str_Relatorio Set @int_MesINI = @int_MesINI + 1 End Set @int_AnoINI = @int_AnoINI + 1 End Set @int_RelatorioINI = @int_RelatorioINI + 1End
Espero ter ajudado
-
Olá Gustavo,
bom pra falar a verdade não entendi muito bem esse teu código, mas como vc disse bem no inicio do teu post (Se fosse no 2000 teríamos um sensível trabalho........) eu lembrei que o servidor em produção aqui da empresa é Sql Sever 2000; apenas o meu aqui de desenvolvimento que é SQL Server 2005 express.
Como posso fazer aqueles loops aninhados com indexação de vetores dentro de uma procedures? No aguardo online. -
-
-
-
-
Olá Gustavo, os dados vão ser sempre constantes. A lógica é a mesma do código abaixo.
Dim meses() as string = {"jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"}
Dim anos() as integer = {2007,2008,2009,2010,2011,2012,2013,2014,2015}
Dim relatorios() as string = {"A","B","C","D"}
Dim ano as integer
Dim mes, relatorio as string
FOR EACH relatorio IN relatorios
FOR EACH ano IN anos
FOR EACH mes IN meses
<< EXEC GET_INDICADOR @mes, @ano, @relatorio >>NEXT
NEXT
Anderson, executei o código que vc me passou e a saida foi a seguinte:
Exec 2007 Jan A
Exec 2007 Fev A
Exec 2007 Mar A
Exec 2007 abr A
Exec 2007 Mai A
Exec 2007 Jun A
Exec 2007 Jul A
Exec 2007 Ago A
Exec 2007 Set A
Exec 2007 Out A
Exec 2007 Nov A
Exec 2007 Dez A
(25 row(s) affected)
(0 row(s) returned)
@RETURN_VALUE = 0
Finished running [dbo].[StoredProcedure1].
O loop interno é o único que está executando; o outros 02 mais externos não estando rodando. Pq? No aguardo. -
-
Caro Marcello, traduza para inerguminos ahauhuahauahuahauh...............talvez eu entenda ahuahu......no aguado.
Pessoal, fiz algumas modificações no código do Anderson (tipo adicionar o campo identidade Codigo_Ano na tabela @vet_anos), porém ele executa apenas o loop interno e depois para a execução. Alguém sabe pq?
ALTER PROCEDURE [dbo].[StoredProcedure1]
AS
Declare @vet_meses Table(Codigo_Mes int identity(1,1),nome char(3))
Declare @vet_anos Table(Codigo_Ano int identity(1,1), Ano int)
Declare @vet_relatorios Table(Codigo_Relatorio int identity(1,1),Nome char(1))
Declare @vet_resultados Table(Codigo_Resultado int identity(1,1),x int, y int, z int)
Insert into @vet_meses values ('Jan')
Insert into @vet_meses values ('Fev')
Insert into @vet_meses values ('Mar')
Insert into @vet_meses values ('abr')
Insert into @vet_meses values ('Mai')
Insert into @vet_meses values ('Jun')
Insert into @vet_meses values ('Jul')
Insert into @vet_meses values ('Ago')
Insert into @vet_meses values ('Set')
Insert into @vet_meses values ('Out')
Insert into @vet_meses values ('Nov')
Insert into @vet_meses values ('Dez')
Insert into @vet_anos values (2007)
Insert into @vet_anos values (2008)
Insert into @vet_anos values (2009)
Insert into @vet_anos values (2010)
Insert into @vet_anos values (2011)
Insert into @vet_anos values (2012)
Insert into @vet_anos values (2013)
Insert into @vet_anos values (2014)
Insert into @vet_anos values (2015)
Insert into @vet_relatorios values ('A')
Insert into @vet_relatorios values ('B')
Insert into @vet_relatorios values ('C')
Insert into @vet_relatorios values ('D')
Declare
@int_RelatorioIni int,
@int_RelatorioFim int,
@int_AnoIni int,
@int_AnoFim int,
@int_MesIni int,
@int_MesFim int,
@str_Ano varchar(4),
@str_Mes varchar(3),
@str_Relatorio varchar(10)
Select @int_RelatorioIni = Min(Codigo_Relatorio), @int_RelatorioFim = Max(Codigo_Relatorio) From @vet_Relatorios
Select @int_AnoIni = Min(Codigo_Ano), @int_AnoFim = Max(Codigo_Ano) From @vet_anos
Select @int_MesIni = Min(Codigo_Mes), @int_MesFim = Max(Codigo_Mes) From @vet_meses
print @int_RelatorioINI
print @int_RelatorioFim
print @int_AnoINI
print @int_AnoFim
print @int_MesINI
print @int_MesFIM
While @int_RelatorioINI <= @int_RelatorioFim
Begin
While @int_AnoINI <= @int_AnoFim
Begin
While @int_MesINI <= @int_MesFIM
Begin
Set @int_MesINI = @int_MesINI + 1
End
Set @int_AnoINI = @int_AnoINI + 1
End
Set @int_RelatorioINI = @int_RelatorioINI + 1
End
RETURN -
Pessoal, descobri o erro de lógica na procedure [um erro bem primário]; esqueci de inicializar novamente as variaveis no inicio de cada um dos 02 loops interno. é a vida......vai o código que resolveu o problema da pergunta 1.
Agradeço a todos pela atenção e marcerei todas as que forem úteis. Att.
ALTER PROCEDURE [dbo].[StoredProcedure1]
AS
Declare @vet_meses Table(Codigo_Mes int identity(1,1),nome char(3))
Declare @vet_anos Table(Codigo_Ano int identity(1,1), Ano int)
Declare @vet_relatorios Table(Codigo_Relatorio int identity(1,1),Nome char(1))
Declare @vet_resultados Table(Codigo_Resultado int identity(1,1),x int, y int, z int)
Insert into @vet_meses values ('Jan')
Insert into @vet_meses values ('Fev')
Insert into @vet_meses values ('Mar')
Insert into @vet_meses values ('abr')
Insert into @vet_meses values ('Mai')
Insert into @vet_meses values ('Jun')
Insert into @vet_meses values ('Jul')
Insert into @vet_meses values ('Ago')
Insert into @vet_meses values ('Set')
Insert into @vet_meses values ('Out')
Insert into @vet_meses values ('Nov')
Insert into @vet_meses values ('Dez')
Insert into @vet_anos values (2007)
Insert into @vet_anos values (2008)
Insert into @vet_anos values (2009)
Insert into @vet_anos values (2010)
Insert into @vet_anos values (2011)
Insert into @vet_anos values (2012)
Insert into @vet_anos values (2013)
Insert into @vet_anos values (2014)
Insert into @vet_anos values (2015)
Insert into @vet_relatorios values ('A')
Insert into @vet_relatorios values ('B')
Insert into @vet_relatorios values ('C')
Insert into @vet_relatorios values ('D')
Declare
@int_RelatorioIni int,
@int_RelatorioFim int,
@int_AnoIni int,
@int_AnoFim int,
@int_MesIni int,
@int_MesFim int,
@str_Ano nvarchar(4),
@str_Mes nvarchar(3),
@str_Relatorio varchar(10)
Select @int_RelatorioIni = Min(Codigo_Relatorio), @int_RelatorioFim = Max(Codigo_Relatorio) From @vet_Relatorios
Select @int_AnoIni = Min(Codigo_Ano), @int_AnoFim = Max(Codigo_Ano) From @vet_anos
Select @int_MesIni = Min(Codigo_Mes), @int_MesFim = Max(Codigo_Mes) From @vet_meses
--print @int_RelatorioINI
--print @int_RelatorioFim
--print @int_AnoINI
--print @int_AnoFim
--print @int_MesINI
--print @int_MesFIM
SET @int_RelatorioINI = 1
While @int_RelatorioINI <= @int_RelatorioFim
Begin
SET @int_AnoINI = 1
While @int_AnoINI <= @int_AnoFim
Begin
SET @int_MesINI = 1
While @int_MesINI <= @int_MesFIM
Begin
Insert into @vet_resultados values (@int_MesINI,@int_AnoINI,@int_RelatorioINI)
Set @int_MesINI = @int_MesINI + 1
End
Set @int_AnoINI = @int_AnoINI + 1
End
Set @int_RelatorioINI = @int_RelatorioINI + 1
End
SELECT * FROM @vet_resultados
RETURN -
Olá Newton,
O SELECT abaixo retorna os comandos que você deseja executar ?
Code SnippetDeclare
@Num TABLE (Num TINYINT)INSERT
INTO @NumSELECT
01 UNION ALL SELECT 02 UNION ALL SELECT 03 UNION ALLSELECT
04 UNION ALL SELECT 05 UNION ALL SELECT 06 UNION ALLSELECT
07 UNION ALL SELECT 08 UNION ALL SELECT 09 UNION ALLSELECT
10 UNION ALL SELECT 11 UNION ALL SELECT 12-- Montando todas as instruções de execução
SET
LANGUAGE Portuguese-- Montando todas as instruções de execução
SELECT
'EXEC AlgumaSP @Mes = '
+ CHAR(39) + Mes + CHAR(39) +', @Ano = '
+ CAST(Ano AS CHAR(4)) FROM (SELECT
LEFT(
DATENAME(M,DATEADD(M,N1.NUM-1,'20080101')),3) AS Mes,2007
+ N2.Num - 1 AS AnoFROM
@Num AS N1, @Num AS N2WHERE
2007 + N2.Num - 1 <= 2015) AS QORDER
BY Ano[ ]s,
Gustavo
-