2009-11-13 13 views
68

Necesito declarar 12 variables decimales, que corresponden al año de cada mes, con un cursor que suma valores a estas variables, luego, actualizo la información de ventas.¿Cómo declarar una matriz dentro del procedimiento almacenado en el servidor Sql?

No sé si el servidor SQL tiene esta sintaxis

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

Este código funciona 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 

Respuesta

123

usted podría declarar una variable de tabla (Declarar una variable de tipo tabla):

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

Puede agregar columnas adicionales como desee:

declare @MonthsSale table(monthnr int, totalsales tinyint) 

puede actualizar la variable de tabla como cualquier otra tabla:

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

T-SQL no admite matrices de las que tenga conocimiento.

¿Cuál es la estructura de su tabla? Probablemente se podría diseñar una consulta que hace esto en su lugar:

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

Solo como un comentario lateral, señalaría que la sintaxis T [n] .v es un poco más concisa que (seleccione v de T donde T.i = n). En realidad, es un poco más conciso. Me gustaría ver que T-SQL lo agregue. – debater

22

¿Hay algún motivo por el que no esté utilizando una variable de tabla y el operador SUM agregado, en lugar de un cursor? SQL sobresale en operaciones orientadas a conjuntos. 99,87% de las veces que usted se encuentra utilizando un cursor, hay una alternativa orientada a conjuntos que es más 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 
+8

Aparentemente en MSSQL2012 ahora puede insertar en este formato: VALORES (1, 'Enero', 100.00), (2, 'Febrero', 200.00) - fuente: http://blog.sqlauthority.com/2012/10/ 27/sql-server-storage-variable-values-in-temporary-array-or-temporary-list/ – andrewb

+2

Esta característica se me escapó por completo; aparentemente eso también funciona en SQL 2008. –

1

Muy buena pregunta y una gran idea, pero en SQL que necesita para hacer esto:

Para el tipo de datos de fecha y hora, algo parecido a esto:

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 todo lo que realmente quiere decir números, hacer esto:

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 
Cuestiones relacionadas