Wie deklariere ich ein Array in MS SQL Server Stored Procedure?

85

Ich muss 12 Dezimalvariablen deklarieren, die dem Jahr eines jeden Monats entsprechen. Mit einem Cursor summiere ich die Werte zu diesen Variablen und aktualisiere später einige Verkaufsinformationen.

Ich weiß nicht, ob SQL Server diese Syntax hat

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

Dieser Code funktioniert in Ordnung. !

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
quelle

Antworten:

142

Sie können eine Tabellenvariable deklarieren (Deklarieren einer Variablen vom Typ table):

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

Sie können nach Belieben zusätzliche Spalten hinzufügen:

declare @MonthsSale table(monthnr int, totalsales tinyint)

Sie können die Tabellenvariable wie jede andere Tabelle aktualisieren:

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

Gibt es einen Grund, warum Sie keine Tabellenvariable und den aggregierten SUM-Operator anstelle eines Cursors verwenden? SQL zeichnet sich durch satzorientierte Operationen aus. In 99,87% der Fälle, in denen Sie einen Cursor verwenden, gibt es eine satzorientierte Alternative, die effizienter ist:

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
quelle
12
Anscheinend können Sie in MSSQL2012 jetzt folgendes Format einfügen: VALUES (1, 'January', 100.00), (2, 'February', 200.00) - Quelle: blog.sqlauthority.com/2012/10/27/…
andrewb
3
Diese Funktion ist mir völlig entgangen. anscheinend funktioniert das auch in SQL 2008.
Paul Smith
8

T-SQL unterstützt keine mir bekannten Arrays.

Wie ist Ihre Tabellenstruktur? Sie könnten wahrscheinlich eine Abfrage entwerfen, die dies stattdessen tut:

select
month,
sum(sales)
from sales_table
group by month
order by month
Patrick Burleson
quelle
Nur als Nebenkommentar möchte ich darauf hinweisen, dass die Syntax T [n] .v etwas prägnanter ist als (wählen Sie v aus T, wobei Ti = n ist). Eigentlich ist es viel prägnanter. Ich würde gerne sehen, wie T-SQL es hinzufügt.
Debater
3

Gute Frage und gute Idee, aber in SQL müssen Sie dies tun:

Für den Datentyp datetime gilt Folgendes:

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

Wenn alles, was Sie wirklich wollen, Zahlen sind, tun Sie dies-

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
Däne Thomas
quelle