Есть несколько способов, которыми я мог бы переработать ваше решение.
Если вы ограничены в том, что вы можете изменить, тогда № 2 может быть билетом.Но мое личное предпочтение было бы № 1 - полученный код проще, и нет никаких изменений, если вы решите, что вам нужен T46.
Подход № 1:
Вы не предоставили полную информацию о своих таблицах, поэтому я предполагаю, что у вас есть столбец ID
, который составляет первичный ключ, или, если нет, мы добавим его в новое решение:)
Я также собираюсь предположить, что вы получаете nvarchar
параметры в свой сохраненный процесс по необходимости, а не по выбору, и соответственно объявляете типы данных.
Это редизайн вашей модели данных извопроса?Один из способов сделать это - переместить столбцы "T1" .. "T45" в отдельную таблицу и рассматривать их как строки.
Вы можете перейти из таблицы:
Create Table ProductProperty
(
ID int identity,
Partno nvarchar(20),
PPFno nvarchar(20),
DName nvarchar(30),
T1 decimal(18, 3),
T2 decimal(18, 3),
T3 decimal(18, 3),
-- ...
T44 decimal(18, 3),
T45 decimal(18, 3),
average decimal(18, 3),
Judgement nvarchar(2)
)
к
Create Table ProductProperty
(
ID int identity,
Partno nvarchar(20),
PPFno nvarchar(20),
DName nvarchar(30),
average decimal(18, 3),
Judgement nvarchar(2)
) -- You would probably want to put a unique index on (Partno, PPFno, DName)
Create Table ProductPropertyT
(
ProductPropertyID int,
TNo nvarchar(2),
TValue decimal(18, 3)
)
Теперь вашей хранимой процедуре просто необходимо определить значение первичного ключа (основываясь на предположении, чтосоставной ключ Partno
, PPFno
и DName
), создайте или обновите запись в таблице ProductPropertyT
и выполните простое среднее значение по TValue
для тех записей с совпадающим значением ProductPropertyId
:
alter procedure [dbo].[saveProdPropSampDta]
@PartNo as nvarchar(20),
@PPFno as nvarchar(20),
@Dimension as nvarchar(30),
@ToUpdate as nvarchar(10),
@count as nvarchar(2),
@Judgement as nvarchar(2)
as
begin
--remove spaces from variable @dimension
set @Dimension = REPLACE(@Dimension, ' ','')
-- determine the PK
declare @pk int
select @pk = ID from ProductProperty where Partno = @Partno and PPFno = @PPFno and DName = @Dimension
-- create / update the value in the ProductPropertyT table
if exists (select * from ProductPropertyT where ProductPropertyID = @pk and TNo = @count)
begin
update ProductPropertyT
set TValue = cast(@ToUpdate as decimal(18, 3))
where ProductPropertyID = @pk and TNo = @count
end
else
begin
insert into ProductPropertyT (ProductPropertyID, TNo, TValue)
values (@pk, @count, cast(@ToUpdate as decimal(18, 3)))
end
-- update the average and judgement in the ProductProperty table.
update ProductProperty
set average = (select avg(TValue) from ProductPropertyT where ProductPropertyID = @pk)
,Judgement = @Judgement
where ID = @pk
end
Сохраненный процесс теперь: короче;не имеет динамического sql;довольно просто понять.
Подход № 2:
Если вам абсолютно необходима эта модель данных, то вы можете использовать unpivot
, чтобы получить ненулевое значениезначения из столбцов T1 ... T45 и просто усредните их.
SELECT avg(TValue)
from
(
-- this will give you only the values for the current part/ppf/dimension
select * from ProductProperty
where Partno = @Partno and PPFno = @PPFno and DName = @Dimension
) myrow
unpivot
(
TValue
for TCol in (T1, T2, ... T44, T45)
) as x
Я оставлю это в качестве упражнения для вас, чтобы включить это в оператор обновления - но достаточно сказать, что вам не нужнолюбой динамический sql для этой части вашей процедуры.
Надеюсь, это поможет.