Обновите столбец при изменении ценового столбца другой таблицы.Триггеры.Вложенные таблицы.SQL Server - PullRequest
0 голосов
/ 21 мая 2018

В моей базе данных у меня около 10 таблиц, связанных в одну центральную таблицу (Mobile).Эта таблица (Mobile) имеет столбец с именем price, который является суммой цен всех других вложенных таблиц.Мне бы хотелось, чтобы при обновлении price другой таблицы (например, Battery, Camera, ...) также обновлялась цена центральной таблицы (Mobile).

Я покажу схему центральной таблицы и еще две (для сокращения кода другие вложенные таблицы очень похожи)

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[table_mobile]
(
    [id] [int] IDENTITY(1,1) NOT NULL,
    [name] [varchar](50) NOT NULL,
    [processor] [int] NOT NULL,
    [memory_ram] [int] NOT NULL,
    [memory_rom] [int] NOT NULL,
    [operating_system] [int] NOT NULL,
    [graphic] [int] NOT NULL,
    [screen] [int] NOT NULL,
    [battery] [int] NOT NULL,
    [camera] [int] NOT NULL,
    [material] [int] NOT NULL,
    [extra] [int] NOT NULL,
    [price] [decimal](18, 2) NOT NULL,
    [created_by] [int] NOT NULL,
    [created_at] [timestamp] NOT NULL,

    CONSTRAINT [PK_mobiles] 
        PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[table_battery]
(
    [id] [int] IDENTITY(1,1) NOT NULL,
    [name] [varchar](50) NOT NULL,
    [capacity] [int] NOT NULL,
    [description] [varchar](250) NOT NULL,
    [image] [image] NOT NULL,
    [price] [decimal](18, 2) NOT NULL,

    CONSTRAINT [PK_table_battery] 
        PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[table_camera]
(
    [id] [int] IDENTITY(1,1) NOT NULL,
    [name] [varchar](50) NOT NULL,
    [megapixels] [int] NOT NULL,
    [description] [varchar](250) NOT NULL,
    [image] [image] NOT NULL,
    [price] [decimal](18, 2) NOT NULL,

    CONSTRAINT [PK_table_camera] 
        PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

Как я уже сказал, я думаю, что моя цель должна быть достигнутас trigger, но любые другие предложения принимаются.

Я покажу вам, что я хочу сделать, программируя на C #:

table_mobile.price = table_battery.price + table_camera.price + ... + table_XXX.price

Любая идея, как мне решить мою проблему?

Спасибо.

РЕДАКТ. 1:

Использование SSMS ... Я создал этот шаблон для триггера:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TRIGGER <Schema_Name, sysname, Schema_Name>.<Trigger_Name, sysname, Trigger_Name> 
   ON  <Schema_Name, sysname, Schema_Name>.<Table_Name, sysname, Table_Name> 
   AFTER <Data_Modification_Statements, , INSERT,DELETE,UPDATE>
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here

END
GO

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Это пример представления, о котором я упоминал:

create view MobileWithPriceAggregate as
select  [id]
,   [name]
,   [processor]
,   [memory_ram]
,   [memory_rom]
,   [operating_system]
,   [graphic]
,   [screen]
,   [battery]
,   [camera]
,   [material]
,   [extra]
, price = m.price+b.price+c.price
from [table_mobile] m
    join [table_battery] b on b.id=m.battery
    join [table_camera] c on c.id=m.camera

Примечание: если не у всех мобильных телефонов есть камера, вам нужно использовать левое соединение и нулевой дескриптор, например ISNULL (c.price, 0)

0 голосов
/ 21 мая 2018

Я некоторое время не работал с SQL Server, так что извините, если есть какие-либо опечатки, но в основном вам нужно будет создать триггер для каждой из таблиц, связанных с мобильными устройствами, и добавить разницу между новой и старойзначение для цены мобильного телефона:

create trigger PriceChange on table_battery
after update
as
BEGIN
update table_mobile
set price = table_mobile.price + i.price
from table_mobile
inner join INSERTED i
on table.mobile.id = i.id;

update table_mobile
set price = table_mobile.price - d.price
from table_mobile
inner join DELETED d
on table.mobile.id = d.id;
END

Обратите внимание, что мы делаем отдельные обновления, потому что идентификатор мог измениться.Если идентификатор остается прежним, то вы можете использовать одно обновление с разницей.Код не проверен, поэтому, если возникнут какие-либо проблемы, пожалуйста, сообщите мне.

РЕДАКТИРОВАТЬ

Вы также можете сделать это на уровне приложения, где вы запускаете обновления.После любого такого обновления вы можете запустить обновление для table_mobile, добавив значения.Преимущество состоит в том, что вы можете выполнить расчет только один раз, если знаете, что будут изменены несколько цен на одни и те же мобильные телефоны.

EDIT2

Очевидно, эту команду следует использовать внутри триггера:

UPDATE [dbo].[table_mobile] 
SET price = table_mobile.price + i.price - d.price 
FROM [dbo].[table_mobile], 
INSERTED i, 
DELETED d 
WHERE battery = d.id
...