95 votes

Comment déclarer un tableau dans une procédure stockée MS SQL Server ?

J'ai besoin de déclarer 12 variables décimales, correspondant à l'année de chaque mois, avec un curseur je fais la somme des valeurs de ces variables, puis plus tard je mets à jour des informations sur les ventes.

Je ne sais pas si le serveur sql a cette syntaxe.

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

Ce code fonctionne bien !

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

157voto

Andomar Points 115404

Vous pouvez déclarer une variable de type tableau (Declaring a variable of type table) :

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

Vous pouvez ajouter des colonnes supplémentaires comme vous le souhaitez :

declare @MonthsSale table(monthnr int, totalsales tinyint)

Vous pouvez mettre à jour la variable de la table comme n'importe quelle autre table :

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

28voto

Paul Smith Points 1064

Y a-t-il une raison pour laquelle vous n'utilisez pas une variable de table et l'opérateur d'agrégation SUM, au lieu d'un curseur ? SQL excelle dans les opérations orientées ensemble. Dans 99,87 % des cas où vous utilisez un curseur, il existe une alternative orientée ensemble qui est plus efficace :

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

14 votes

Apparemment, dans MSSQL2012, vous pouvez maintenant insérer dans ce format : VALUES(1, 'Janvier', 100.00),(2, 'Février', 200.00) - source : blog.sqlauthority.com/2012/10/27/

3 votes

Cette fonctionnalité m'a totalement échappé ; apparemment, cela fonctionne aussi en SQL 2008.

8voto

Patrick Burleson Points 227

T-SQL ne supporte pas les tableaux à ma connaissance.

Quelle est la structure de votre table ? Vous pourriez probablement concevoir une requête qui fasse cela à la place :

select
month,
sum(sales)
from sales_table
group by month
order by month

0 votes

Juste à titre de commentaire, je voudrais noter que la syntaxe T[n].v est un peu plus concise que (select v from T where T.i = n). En fait, c'est un lot plus concis. J'aimerais bien que T-SQL l'ajoute.

3voto

Dane Thomas Points 41

Excellente question et excellente idée, mais en SQL vous devrez faire ceci :

Pour le type de données datetime, quelque chose comme ceci-

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

Si tout ce que tu veux c'est des chiffres, fais ça

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

0voto

Y-Mi Wong Points 41

Vous pouvez déclarer un tableau en utilisant le mot-clé VALUES. Votre exemple peut être exprimé succinctement sous la forme suivante :

SELECT * FROM (VALUES 
    (1,100), 
    (2,200), 
    (3,300), 
    (4,400), 
    (5,500), 
    (6,600), 
    (7,700), 
    (8,800), 
    (9,900), 
    (10,1000), 
    (11,1100), 
    (12,1200)
) MonthSale (monthnr, Amount)

N'hésitez pas à l'INSÉRER dans un tableau ou à placer une condition WHERE ou GROUP pour vos besoins.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X