2015-03-26 1 views
0

Я новичок, который начал самообучающийся SQL/T-SQL. Я работал с SQL 2014 Express и пытаюсь сделать все, написав сценарии T-SQL. Я делаю это, чтобы помочь другу с базой данных для ее живой экшн-игры, которую она пишет, и может использовать некоторую помощь с точки зрения того, чтобы сделать следующую пользовательскую функцию более упорядоченной/записать ее более правильным образом.SQL Server 2014 UDF - функция упорядочения

Эта функция сама по себе считалась необходимой из-за необходимости постоянного расчета для определения экономической ценности предмета. Это казалось лучшим маршрутом, чем попытка сделать какой-то сценарий обновления, который обновлял все значения каждый раз, когда обновлялась таблица Items. Извините, если все это кажется рудиментарным, пытается учиться.

Ниже приведен код. У меня это работает, я получил его в своей базе данных разработки, и он делает то, что должен. Но я бы хотел его очистить, и я не знаю, как это сделать.

CREATE FUNCTION dbo.ValueCalc (@itemid int) 
    RETURNS INT 
    AS 
    BEGIN 
    declare @rm1 int, @rm1amount int, @rm1value int, 
    @rm2 int, @rm2amount int, @rm2value int, 
    @rm3 int, @rm3amount int, @rm3value int, 
    @rm4 int, @rm4amount int, @rm4value int, 
    @cm1 int, @cm1amount int, @cm1value int, 
    @cm2 int, @cm2amount int, @cm2value int, 
    @cm3 int, @cm3amount int, @cm3value int, 
    @cm4 int, @cm4amount int, @cm4value int, 
    @productionvalue int; 

    select @rm1 = MatReqs.RM1 FROM MatReqs WHERE MatReqs.ItemId = @itemid; 
    select @rm1amount = MatReqs.RM1Amount FROM MatReqs WHERE MatReqs.ItemId = @itemid; 
    select @rm1value = RawMats.BaseValue FROM RawMats WHERE RawMats.RawMatId = @rm1; 
    if (@rm1 IS NULL) set @rm1=0; 
    if (@rm1amount IS NULL) set @rm1amount=0; 
    if (@rm1value IS NULL) set @rm1value=0; 

    {Repeat the above 3 more times, for rm2, rm3, and rm4} 

    select @cm1 = MatReqs.CM1 FROM MatReqs WHERE MatReqs.ItemId = @itemid; 
    select @cm1amount = MatReqs.CM1Amount FROM MatReqs WHERE MatReqs.ItemId = @itemid; 
    select @cm1value = Items.ProdValue FROM Items WHERE Items.ItemId = @cm1; 
    if (@cm1 IS NULL) set @cm1=0; 
    if (@cm1amount IS NULL) set @cm1amount=0; 
    if (@cm1value IS NULL) set @cm1value=0; 

    {same here, just removed the repetitions}  

    set @productionvalue = (@rm1amount * @rm1value) 
    + (@rm2amount * @rm2value) 
    + (@rm3amount*@rm3value) 
    + (@rm4amount*@rm4value) 
    + (@cm1amount*@cm1value) 
    + (@cm2amount*@cm2value) 
    + (@cm3amount*@cm3value) 
    + (@cm4amount*@cm4value); 

    set @productionvalue = @productionvalue + (@productionvalue * .15); 

    return @productionvalue; 
    END 
    GO 

ответ

0

Если бы я имел некоторые образцы данных и желаемые результаты и всю свою функцию, я мог бы написать более эффективное решение, как SQL Server оптимизирован для набора на основе кода, и вы на самом деле не использовать его. Что касается простой очистки, вы можете сделать это, но я предпочел бы, чтобы вы опубликовали данные образца и желаемые результаты, и для меня вместо этого вы получите хорошее решение на основе набора.

CREATE FUNCTION dbo.ValueCalc (@itemid INT) 
RETURNS INT 
AS 
BEGIN 
DECLARE @rm1 INT, @rm1amount INT, @rm1value INT, 
     @rm2 INT, @rm2amount INT, @rm2value INT, 
     @rm3 INT, @rm3amount INT, @rm3value INT, 
     @rm4 INT, @rm4amount INT, @rm4value INT, 
     @cm1 INT, @cm1amount INT, @cm1value INT, 
     @cm2 INT, @cm2amount INT, @cm2value INT, 
     @cm3 INT, @cm3amount INT, @cm3value INT, 
     @cm4 INT, @cm4amount INT, @cm4value INT, 
     @productionvalue INT; 

--They both come from the same table with the where clause so just combine them 
SELECT @rm1 = ISNULL(MatReqs.RM1,0), 
     @rm1amount = ISNULL(MatReqs.RM1Amount,0)  
FROM MatReqs 
WHERE MatReqs.ItemId = @itemid; 

SELECT @rm1value = ISNULL(RawMats.BaseValue,0) F 
FROM RawMats 
WHERE RawMats.RawMatId = @rm1; 

--The ISNULL() function will take care of this 
    --if (@rm1 IS NULL) set @rm1=0; 
    --if (@rm1amount IS NULL) set @rm1amount=0; 
    --if (@rm1value IS NULL) set @rm1value=0; 


--Combine the first two statements again 
SELECT @cm1 = ISNULL(MatReqs.CM1,0), 
     @cm1amount = ISNULL(MatReqs.CM1Amount,0) 
FROM MatReqs 
WHERE MatReqs.ItemId = @itemid; 

SELECT @cm1value = ISNULL(Items.ProdValue,0) 
FROM Items 
WHERE Items.ItemId = @cm1; 

--Again just use ISNULL 
    --if (@cm1 IS NULL) set @cm1=0; 
    --if (@cm1amount IS NULL) set @cm1amount=0; 
    --if (@cm1value IS NULL) set @cm1value=0;