Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Триггер Instead Of Update  [new]
volt
Member

Откуда:
Сообщений: 105
Добрый день!
Есть представление, которое описано следующим образом:

Create view АссортВсе as
SELECT 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.КодИздел, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.Наимен, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.Стар, 
  [ГлобSQL].dbo.АссортКонф.Цена, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.Назначение, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.ПРименяемость
FROM [Глоб-ПоизводствоSQL].dbo.Ассортимент LEFT JOIN [ГлобSQL].dbo.АссортКонф ON [Глоб-ПоизводствоSQL].dbo.Ассортимент.КодИздел = [ГлобSQL].dbo.АссортКонф.КодИздел
Group by 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.КодИздел, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.Наимен, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.Стар, 
  [ГлобSQL].dbo.АссортКонф.Цена, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.Назначение, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.ПРименяемость


Для него пишу триггер на изменение:

ALTER TRIGGER [dbo].[InsteadUpdateTriggerАссортВсе] on [dbo].[АссортВсе]
INSTEAD OF Update
AS
BEGIN
  declare @Id int
  declare Cur cursor for 
     Select КодИздел From inserted 
  open Cur

  fetch next from Cur into @Id

  while @@FETCH_STATUS = 0 
     begin
		Update [Глоб-ПоизводствоSQL].dbo.Ассортимент  set 
		 Наимен = (Select Наимен from inserted where КодИздел = @Id),
		 Стар = (Select Стар from inserted where КодИздел = @Id),
		 Назначение = (Select Назначение from inserted where КодИздел = @Id),
		 Применяемость = (Select ПРименяемость from inserted where КодИздел = @Id) where КодИздел = @Id
		
		Update [ГлобSQL].dbo.АссортКонф set цена = (Select Цена
	   from inserted where КодИздел = @Id) where КодИздел = @Id
		
		
	   fetch next from Cur into @Id
	 end;
   CLOSE Cur
   DEALLOCATE Cur
  

END;


триггер на изменение создан корректно, теперь при попытке изменить какую либо строку выдается сообщение:
the row value(s) updated or deleted either do not make the row unique or they alter multiple rows

Подскажите, что я не так делаю?
14 фев 18, 16:39    [21191586]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
volt
Подскажите, что я не так делаю?

Курсор в триггере, обожемой, какой верный способ убить производительность.

Осознайте, что inserted и deleted - это таблицы, и общаться с ними надо как с таблицами, через join'ы.
14 фев 18, 16:46    [21191618]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
volt,

говорит что не понимает ваших приколов со сгруппированным предаставлением

https://msdn.microsoft.com/en-us/library/ms180800(v=sql.105).aspx
14 фев 18, 16:56    [21191664]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
volt
Member

Откуда:
Сообщений: 105
TaPaK,

Я поэтому и пытаюсь триггер типа Instead of Update, т.к. стандартный функционал представления и не понимает как работать с представлениями из нескольких таблиц.
14 фев 18, 17:13    [21191736]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
volt
TaPaK,

Я поэтому и пытаюсь триггер типа Instead of Update, т.к. стандартный функционал представления и не понимает как работать с представлениями из нескольких таблиц.

какой пункт вам не понятен в предложении или ссылке?
14 фев 18, 17:14    [21191743]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
invm
Member

Откуда: Москва
Сообщений: 9128
volt
Подскажите, что я не так делаю?
Если честно, то все.

Во-первых, добаваьте к представление опцию metadata
Во-вторых, set nocount on в начало триггера.
В-третьих, мало того, что курсор, так еще и inserted сканируется шесть раз вместо одного...
14 фев 18, 17:41    [21191847]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
iap
Member

Откуда: Москва
Сообщений: 46954
invm
volt
Подскажите, что я не так делаю?
Если честно, то все.

Во-первых, добаваьте к представление опцию metadata
Во-вторых, set nocount on в начало триггера.
В-третьих, мало того, что курсор, так еще и inserted сканируется шесть раз вместо одного...
VIEW_METADATA
14 фев 18, 18:13    [21191946]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5112
volt,

у вас в тригере везде КодИздел = @Id
уверены, что inserted возвращает уникальные КодИздел (с учётом того, что во вьюхе у вас left join по нему)
14 фев 18, 18:16    [21191962]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
Дедушка
volt,

у вас в тригере везде КодИздел = @Id
уверены, что inserted возвращает уникальные КодИздел (с учётом того, что во вьюхе у вас left join по нему)

и что что есть left join?

Зачем в принципе заниматься модификацией сгруппированного представления.. триггером.. не ясен :)
14 фев 18, 18:27    [21191996]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
volt
Member

Откуда:
Сообщений: 105
Дедушка,

Как проверить, что содержится в inserted?
16 фев 18, 10:20    [21195945]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
aleksrov
Member

Откуда:
Сообщений: 948
volt
Дедушка,

Как проверить, что содержится в inserted?


Через exist, типа
update table 
set --bla bla
from iserted i
where i.id = table.id

типо того.
Также добавить if @@rowcount = 0 return.
Также сделать проверку через функцию Update на нужные столбцы.
16 фев 18, 10:39    [21196021]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
aleksrov,

автор
if @@rowcount = 0 return.

MERGE смеётся над этим условием
16 фев 18, 10:40    [21196022]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
aleksrov
Member

Откуда:
Сообщений: 948
Какого я exist написал... О другом видимо подумал.
16 фев 18, 10:41    [21196026]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
aleksrov
Member

Откуда:
Сообщений: 948
TaPaK,

ok, если совсем быть пуристом
if not exists (select * from inserted)
return
16 фев 18, 10:44    [21196045]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
volt
Member

Откуда:
Сообщений: 105
TaPaK,

Убрал группировку, из представления, все равно не дает модифицировать
16 фев 18, 11:14    [21196173]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
volt
TaPaK,

Убрал группировку, из представления, все равно не дает модифицировать

и поставили DISTINCT?
16 фев 18, 11:16    [21196179]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
volt
Member

Откуда:
Сообщений: 105
TaPaK,

в данный момент представление выглядит следующим образом:
SELECT DISTINCT 
                         [Глоб-ПоизводствоSQL].dbo.Ассортимент.КодИздел, [Глоб-ПоизводствоSQL].dbo.Ассортимент.Наимен, [Глоб-ПоизводствоSQL].dbo.Ассортимент.Стар, 
                         ГлобSQL.dbo.АссортКонф.Цена, [Глоб-ПоизводствоSQL].dbo.Ассортимент.Назначение, [Глоб-ПоизводствоSQL].dbo.Ассортимент.ПРименяемость
FROM            [Глоб-ПоизводствоSQL].dbo.Ассортимент LEFT OUTER JOIN
                         ГлобSQL.dbo.АссортКонф ON [Глоб-ПоизводствоSQL].dbo.Ассортимент.КодИздел = ГлобSQL.dbo.АссортКонф.КодИздел
16 фев 18, 11:42    [21196306]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
TaPaK
volt
TaPaK,

Убрал группировку, из представления, все равно не дает модифицировать

и поставили DISTINCT?

пойду в лотерею играть
16 фев 18, 11:47    [21196327]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
volt
Member

Откуда:
Сообщений: 105
TaPaK,

Не работает не с дистинктом, ни без него...

SELECT        [Глоб-ПоизводствоSQL].dbo.Ассортимент.КодИздел, [Глоб-ПоизводствоSQL].dbo.Ассортимент.Наимен, [Глоб-ПоизводствоSQL].dbo.Ассортимент.Стар, 
                         ГлобSQL.dbo.АссортКонф.Цена, [Глоб-ПоизводствоSQL].dbo.Ассортимент.Назначение, [Глоб-ПоизводствоSQL].dbo.Ассортимент.ПРименяемость
FROM            [Глоб-ПоизводствоSQL].dbo.Ассортимент LEFT OUTER JOIN
                         ГлобSQL.dbo.АссортКонф ON [Глоб-ПоизводствоSQL].dbo.Ассортимент.КодИздел = ГлобSQL.dbo.АссортКонф.КодИздел
16 фев 18, 13:01    [21196612]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
volt,
а давайте начнем с чтения Документации
16 фев 18, 13:09    [21196655]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
volt,

вы это с дизайнера что-ли делаете? :)
16 фев 18, 13:28    [21196746]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
volt
Member

Откуда:
Сообщений: 105
TaPaK,

Нет, это просто результат работы. Я создаю представление следующим образом:

Create view АссортВсе2 with view_metadata as
SELECT 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.КодИздел, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.Наимен, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.Стар, 
  [ГлобSQL].dbo.АссортКонф.Цена, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.Назначение, 
  [Глоб-ПоизводствоSQL].dbo.Ассортимент.ПРименяемость
FROM [Глоб-ПоизводствоSQL].dbo.Ассортимент LEFT JOIN [ГлобSQL].dbo.АссортКонф ON [Глоб-ПоизводствоSQL].dbo.Ассортимент.КодИздел = [ГлобSQL].dbo.АссортКонф.КодИздел


Затем создаю триггер:
USE [ТехноSQL]
GO
/****** Object:  Trigger [dbo].[InsteadUpdateTriggerAssortimentPoln1]    Script Date: 12.02.2018 10:54:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON

go
Create TRIGGER [dbo].[InsteadUpdateTriggerАссортВсе2] on [dbo].[ассортВсе2]
INSTEAD OF Update
AS
BEGIN
  set nocount on
  declare @Id int
  declare Cur cursor for 
     Select КодИздел From inserted 
  open Cur

  fetch next from Cur into @Id

  while @@FETCH_STATUS = 0 
     begin
		Update [Глоб-ПоизводствоSQL].dbo.Ассортимент  set 
		 Наимен = (Select Наимен from inserted where КодИздел = @Id),
		 Стар = (Select Стар from inserted where КодИздел = @Id),
		 Назначение = (Select Назначение from inserted where КодИздел = @Id),
		 Применяемость = (Select ПРименяемость from inserted where КодИздел = @Id) where КодИздел = @Id
		
		Update [ГлобSQL].dbo.АссортКонф set цена = (Select Цена
	   from inserted where КодИздел = @Id) where КодИздел = @Id
			
	   fetch next from Cur into @Id
	 end;
   CLOSE Cur
   DEALLOCATE Cur
  END;


При попытке изменить, все работает корректно.. Всем спасибо. Вроде решил. Создал все с нуля - и все работает.
16 фев 18, 13:48    [21196826]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
volt,

а курсор зачем?
16 фев 18, 13:53    [21196845]     Ответить | Цитировать Сообщить модератору
 Re: Триггер Instead Of Update  [new]
aleksrov
Member

Откуда:
Сообщений: 948
TaPaK
volt,

а курсор зачем?


А он упертый. Ему уже куча народу ответили как должно быть, даже тот же rowcount не добавил, но он решил сделать через курсор и все, по фиг что тут советует. Потом после таких "мастеров" расхлебывай.
16 фев 18, 18:30    [21197878]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить