#sql #sql-server #tsql #upsert
#sql #sql-сервер #tsql #upsert
Вопрос:
У меня есть таблица, в которой я хотел бы удалить много нулевых столбцов, но я не уверен, что я иду в правильном направлении.
Вот пример SQL, чтобы показать, что я хочу (удаление количества из продуктов):
CREATE TABLE [Products]([Id] [int] NOT NULL,[Name] [varchar](50))
CREATE TABLE [StockProducts]([Id] [int] NOT NULL,[Quantity] [int])
go
insert into Products (Id, [Name]) values (1,'Socks')
insert into Products (Id, [Name]) values (2,'Gloves')
CREATE VIEW ProductStockView as select P.Id, SP.Quantity from Products P left join StockProducts SP on P.Id = SP.Id
go
select * from ProductStockView
go
update ProductStockView set Quantity = 2 where Id = 1
Мне бы очень хотелось, чтобы обновление добавляло вставку в мою таблицу StockProducts, потому что у меня есть все идентификаторы продуктов, и мой существующий код будет продолжать работать.
Существует ли шаблон для этого, или предпочтительным способом было бы просто добавить триггер обновления в представление? Прямо сейчас оператор update выдает: 0 затронутых строк.
Редактировать на основе двух комментариев: Идентификатор двух таблиц следует рассматривать как первичные ключи (для использования в таких средах, как Entity Framework). И мой реальный пример, конечно, заключается в том, что таблица с именем Products в моем примере — это старая таблица, которая у нас есть с 75 столбцами, а ProductStockView — это то, чем я хотел бы заменить ее в частях моего кода.
Комментарии:
1. Я чувствую, что реальный вопрос здесь заключается в том, почему вы обновляете представление
ProductStockView
, а не выполняете обновление (или, скорее, Upsert/MERGE
) противStockProducts
?2. Как минимум, ваш DDL должен содержать правильные ограничения первичного ключа и внешнего ключа, чтобы никто не догадался о ваших намерениях. И трудно предлагать полезные предложения без гораздо лучшего понимания вашей модели. Редко у кого есть одна таблица, которая представляет запасы (или текущий уровень запасов или любой другой подходящий термин). Возможно, ваша модель намного более упрощена и не соответствует реальной ситуации. Если это так, то это важная информация, хотя бы для того, чтобы не вдаваться в подробности, которые не нужны.
3. Вы могли бы использовать
merge
для обработки upsert , т. Е.update
Илиinsert
по мере необходимости. Его можно даже обучитьdelete
, если значениеQuantity
равно нулю.4. К сожалению, ваши варианты — либо заменить ваши инструкции UPDATE на MERGE, как описано выше, либо добавить триггер для ОБНОВЛЕНИЯ таблицы. Если вы предпочитаете вообще не изменять свои инструкции UPDATE, то триггер — ваша единственная надежда.
Ответ №1:
Спасибо за комментарии. Это было именно то, что мне было нужно. Я оставлю ответ здесь:
create trigger ProductStockViewUpdateTrigger
on ProductStockView instead of update
as
MERGE StockProducts as target
USING (SELECT Id, Quantity from inserted) as source
ON target.Id = source.Id
WHEN MATCHED
AND target.Quantity != source.Quantity
THEN UPDATE
SET target.Quantity = source.Quantity
WHEN NOT MATCHED by target
THEN
INSERT ([Id], [Quantity])
values (source.id, source.quantity);