2009-11-13 4 views
68

Muszę zadeklarować 12 zmiennych dziesiętnych, odpowiadających miesiącom każdego miesiąca, kursor I sumuje wartości do tych zmiennych, a następnie aktualizuję niektóre informacje o sprzedaży.Jak zadeklarować tablicę w procedurze składowanej serwera SQL?

ja nie wiem, czy serwer SQL mają tę składnię

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

Ten kod działa OK. !

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 

Odpowiedz

123

Można zadeklarować zmienną stołowego (deklarując zmienną typu tabeli):

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

Możesz dodać dodatkowe kolumny, jak chcesz:

declare @MonthsSale table(monthnr int, totalsales tinyint) 

można zaktualizować zmiennej tabeli jak każdy inny tabeli:

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

T-SQL nie obsługuje tablic, o których mi wiadomo.

Jaka jest struktura stołu? Prawdopodobnie mógł zaprojektować kwerendę, która wykonuje to zamiast:

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

Tylko jako komentarz boczny, chciałbym zauważyć, że składnia T [n] .v jest nieco bardziej zwięzła niż (wybierz v z T, gdzie T.i = n). W rzeczywistości jest to bardziej zwięzłe. Chciałbym, żeby T-SQL go dodał. – debater

22

Czy istnieje powód, dla którego nie używasz zmiennej tabeli i zagregowanego operatora SUM zamiast kursora? SQL wyróżnia się w operacjach zorientowanych na set. 99,87% czasu, aby znaleźć się za pomocą kursora, istnieje zestaw zorientowany alternatywa, która jest bardziej efektywne:

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

Najwyraźniej w MSSQL2012 można teraz wstawić w tym formacie: WARTOŚCI (1, "styczeń", 100,00), (2, "luty", 200,00) - źródło: http://blog.sqlauthority.com/2012/10/ 27/sql-server-storing-variable-values-in-temporary-array-or-temporary-list/ – andrewb

+2

Ta funkcja całkowicie umknęła mojej uwadze; podobno działa to również w SQL 2008. –

1

Wielkie pytanie i świetny pomysł, ale w SQL trzeba to zrobić:

Dla typu danych datetime, coś jak to-

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 

Jeśli wszystko czego naprawdę chcę to numery, wykonaj this-

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