none
Utilização de vetores ( arrays ) em T-SQL para execução de outras procedures RRS feed

  • 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.
    quinta-feira, 25 de setembro de 2008 14:52

Respostas

  • Boa tarde Newton dá uma olhada no exemplo, creio que seja isso

     

    Set Nocount On

    Declare @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_Relatorios

    Select @int_AnoIni = Min(Ano),@int_AnoFim = Max(Ano) From @vet_anos

    Select @int_MesIni = Min(Codigo_Mes),@int_MesFim = Max(Codigo_Mes) From @vet_meses

    While @int_RelatorioINI <= @int_RelatorioFim

    Begin

    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 + 1

    End

     

     

     

    Espero ter ajudado

    quinta-feira, 25 de setembro de 2008 16:25

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 Snippet

    DECLARE @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

    quinta-feira, 25 de setembro de 2008 16:20
  • Boa tarde Newton dá uma olhada no exemplo, creio que seja isso

     

    Set Nocount On

    Declare @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_Relatorios

    Select @int_AnoIni = Min(Ano),@int_AnoFim = Max(Ano) From @vet_anos

    Select @int_MesIni = Min(Codigo_Mes),@int_MesFim = Max(Codigo_Mes) From @vet_meses

    While @int_RelatorioINI <= @int_RelatorioFim

    Begin

    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 + 1

    End

     

     

     

    Espero ter ajudado

    quinta-feira, 25 de setembro de 2008 16:25

  • 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.
    quinta-feira, 25 de setembro de 2008 16:27
  • Olá Anderson, esse código roda em SQL Server 2000 [pois este é o servidor de produção; o SQL Server 2005 express é apenas o banco de desenvolvimento - localhost ] ?? Fico no aguardo online.
    quinta-feira, 25 de setembro de 2008 16:31

  • Só uma coisa Anderson, essa tabela que vc cria na procedure é temporária? Senão, qual select eu devo usar pra saber se essa tabela existe no banco? No aguardo.

    quinta-feira, 25 de setembro de 2008 16:35
  • Pode rodar sem medo de ser feliz, é uma tabela de memória.

     

     

     

    Abraço

    quinta-feira, 25 de setembro de 2008 16:36
  • Olá Newton,

     

    Quantos membros em média você espera receber em um Array ?

    Após separar os membros o que você pretende fazer ?

     

    [ ]s,

     

    Gustavo

    quinta-feira, 25 de setembro de 2008 16:53

  • 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.
    quinta-feira, 25 de setembro de 2008 17:03
  • se e fixo cria uma tabela de Lookups assim fica mais simples de trabalhar.

     

    Abs;

     

    quinta-feira, 25 de setembro de 2008 17:27

  • 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
    quinta-feira, 25 de setembro de 2008 17:50
  • 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
    quinta-feira, 25 de setembro de 2008 18:04
  • Olá Newton,

     

    O SELECT abaixo retorna os comandos que você deseja executar ?

     

    Code Snippet

    Declare @Num TABLE (Num TINYINT)

    INSERT INTO @Num

    SELECT 01 UNION ALL SELECT 02 UNION ALL SELECT 03 UNION ALL

    SELECT 04 UNION ALL SELECT 05 UNION ALL SELECT 06 UNION ALL

    SELECT 07 UNION ALL SELECT 08 UNION ALL SELECT 09 UNION ALL

    SELECT 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 Ano

    FROM @Num AS N1, @Num AS N2

    WHERE 2007 + N2.Num - 1 <= 2015) AS Q

    ORDER BY Ano

     

     

    [ ]s,

     

    Gustavo

    quinta-feira, 25 de setembro de 2008 18:04
  • Obrigado pela ajuda e atenção Gustavo, mas não entendi bem seu código; bem provavelmente porque não tenho um conhecimento profundo sobre SQL server; mas foi útil. Att.
    quinta-feira, 25 de setembro de 2008 18:10