Como declarar um array dentro do procedimento armazenado do MS SQL Server?

85

Preciso declarar 12 variáveis ​​decimais, correspondentes ao ano de cada mês, com um cursor soma os valores a essas variáveis, depois atualizo algumas informações de vendas.

Não sei se o servidor sql tem essa sintaxe

 Declare MonthsSale(1 to 12) as decimal(18,2)

Este código funciona bem. !

CREATE PROCEDURE [dbo].[proc_test]
AS
BEGIN

--SET NOCOUNT ON;

DECLARE @monthsales TABLE ( monthnr int,    amount decimal(18,2)    )


-- PUT YOUR OWN CODE HERE


-- THIS IS TEST CODE
-- 1 REPRESENTS JANUARY, ...
INSERT @monthsales (monthnr, amount) VALUES (1, 100)
INSERT @monthsales (monthnr, amount) VALUES (1, 100)

INSERT @monthsales (monthnr, amount) VALUES (2, 200)
INSERT @monthsales (monthnr, amount) VALUES (3, 300)
INSERT @monthsales (monthnr, amount) VALUES (4, 400)
INSERT @monthsales (monthnr, amount) VALUES (5, 500)
INSERT @monthsales (monthnr, amount) VALUES (6, 600)
INSERT @monthsales (monthnr, amount) VALUES (7, 700)
INSERT @monthsales (monthnr, amount) VALUES (8, 800)
INSERT @monthsales (monthnr, amount) VALUES (9, 900)
INSERT @monthsales (monthnr, amount) VALUES (10, 1000)
INSERT @monthsales (monthnr, amount) VALUES (11, 1100)
INSERT @monthsales (monthnr, amount) VALUES (12, 1200)


SELECT monthnr, SUM(amount) AS SUM_MONTH_1 FROM @monthsales WHERE monthnr = 1 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_2 FROM @monthsales WHERE monthnr = 2 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_3 FROM @monthsales WHERE monthnr = 3 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_4 FROM @monthsales WHERE monthnr = 4 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_5 FROM @monthsales WHERE monthnr = 5 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_6 FROM @monthsales WHERE monthnr = 6 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_7 FROM @monthsales WHERE monthnr = 7 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_8 FROM @monthsales WHERE monthnr = 8 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_9 FROM @monthsales WHERE monthnr = 9 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_10 FROM @monthsales WHERE monthnr = 10 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_11 FROM @monthsales WHERE monthnr = 11 GROUP BY monthnr
SELECT monthnr, SUM(amount) AS SUM_MONTH_12 FROM @monthsales WHERE monthnr = 12 GROUP BY monthnr

-- END TEST CODE
END
RicardoBalda
fonte

Respostas:

143

Você pode declarar uma variável de tabela (Declarando uma variável do tipo tabela):

declare @MonthsSale table(monthnr int)
insert into @MonthsSale (monthnr) values (1)
insert into @MonthsSale (monthnr) values (2)
....

Você pode adicionar colunas extras conforme desejar:

declare @MonthsSale table(monthnr int, totalsales tinyint)

Você pode atualizar a variável da tabela como qualquer outra tabela:

update m
set m.TotalSales = sum(s.SalesValue)
from @MonthsSale m
left join Sales s on month(s.SalesDt) = m.MonthNr
Andomar
fonte
26

Existe um motivo pelo qual você não está usando uma variável de tabela e o operador SUM agregado, em vez de um cursor? SQL é excelente em operações orientadas a conjuntos. 99,87% das vezes que você usa um cursor, há uma alternativa orientada a conjuntos que é mais eficiente:

declare @MonthsSale table
(
MonthNumber int,
MonthName varchar(9),
MonthSale decimal(18,2)
)

insert into @MonthsSale
select
    1, 'January', 100.00
union select    
    2, 'February', 200.00
union select    
    3, 'March', 300.00
union select    
    4, 'April', 400.00
union select    
    5, 'May', 500.00
union select    
    6, 'June', 600.00
union select    
    7, 'July', 700.00
union select    
    8, 'August', 800.00
union select    
    9, 'September', 900.00
union select    
    10, 'October', 1000.00
union select    
    11, 'November', 1100.00
union select    
    12, 'December', 1200.00

select * from @MonthsSale   
select SUM(MonthSale) as [TotalSales] from @MonthsSale
Paul Smith
fonte
12
Aparentemente, no MSSQL2012 você agora pode inserir neste formato: VALORES (1, 'janeiro', 100,00), (2, 'fevereiro', 200,00) - fonte: blog.sqlauthority.com/2012/10/27/…
andrewb
3
Esse recurso escapou totalmente da minha atenção; aparentemente isso funciona no SQL 2008 também.
Paul Smith
8

Que eu saiba, o T-SQL não oferece suporte a matrizes.

Qual é a estrutura da sua tabela? Você provavelmente poderia criar uma consulta que fizesse isso:

select
month,
sum(sales)
from sales_table
group by month
order by month
Patrick Burleson
fonte
Apenas como um comentário lateral, eu observaria que a sintaxe T [n] .v é um pouco mais concisa do que (selecione v de T onde Ti = n). Na verdade, é muito mais conciso. Eu gostaria muito de ver o T-SQL adicioná-lo.
debatedor de
3

Ótima pergunta e ótima ideia, mas no SQL você precisará fazer isso:

Para o tipo de dados datetime, algo como este-

declare @BeginDate    datetime = '1/1/2016',
        @EndDate      datetime = '12/1/2016'
create table #months (dates datetime)
declare @var datetime = @BeginDate
   while @var < dateadd(MONTH, +1, @EndDate)
   Begin
          insert into #months Values(@var)
          set @var = Dateadd(MONTH, +1, @var)
   end

Se tudo o que você realmente quer são números, faça isso-

create table #numbas (digit int)
declare @var int = 1        --your starting digit
    while @var <= 12        --your ending digit
    begin
        insert into #numbas Values(@var)
        set @var = @var +1
    end
Dane Thomas
fonte