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

Откуда: md
Сообщений: 133
Доброго времени суток, уважаемые форумчане.

Прошу помощи в решении задачи и использованием триггера.

Ситуация собственно следующая:

Есть некий софт, работающий с MSSQL 2005/2008 Express Edition.
При нажатии на кпопку "А" происходит запись данных в таблицы orders и order_details, свызанные следующим образом: orders.row_id=order_details.order_id

Создаю триггер:

CREATE TRIGGER [dbo].[insert_details]

ON [db].[dbo].[orders] AFTER INSERT

AS

BEGIN

declare  @id int 
select @id = row_id from inserted

insert into order_details
values ('Client Name','Client',@id)

 
END


При этом, в таблицу order_details строка из триггера не записывается. Добавил в триггер WAITFOR DELAY '00:00:20' перед insert'ом.
В итоге софт записывает данные в order_details с задержкой в 20 секунд, мои данные не записываются, а всё это время таблица orders находится в блокировке.
Проверял следующим способом:

select
  object_name(resource_associated_entity_id) as 'TableName' ,*
from
  sys.dm_tran_locks
where resource_type = 'OBJECT'
  and resource_database_id = DB_ID()
GO

Вот тут возникает вопрос, почему не могу записать данные order_details, ведь она не в блокировке ?
Возможно надо поменять что-то в триггере, подскажите, пожалуйста, что именно.

Спасибо !
15 дек 12, 13:28    [13636161]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
aleks2
Guest
Нада так:
CREATE TRIGGER [dbo].[insert_details]

ON [db].[dbo].[orders] AFTER INSERT

AS

BEGIN

insert into order_details(<надо напесать поля ЯВНО>)
select 'Client Name', 'Client', row_id from inserted;
 
END
15 дек 12, 13:35    [13636169]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
gumeniuc
Member

Откуда: md
Сообщений: 133
aleks2,

В таблице order_details row_id (инкремент) + 3 столбца, SQL сам поочерёдно загонит данные в соответствующем порядке.
Если insert запустить отдельно, всё отлично работает.
15 дек 12, 13:41    [13636176]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
aleks2
Guest
gumeniuc
aleks2,

В таблице order_details row_id (инкремент) + 3 столбца, SQL сам поочерёдно загонит данные в соответствующем порядке.
Если insert запустить отдельно, всё отлично работает.


1. Не, ну, ты могешь продолжать искать бубен.
2. Для особо мнительных - есть отладчик.
15 дек 12, 13:46    [13636184]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
gumeniuc
Member

Откуда: md
Сообщений: 133
aleks2,

Вот ещё агрумент - если софт не пишет в таблицу order_details, то триггер работает на ура. Тут дело не в синтаксисе инсерта. Я поэтому и спросил, правильно ли написан триггер AFTER и как записать данные уже после блокировки.
15 дек 12, 13:49    [13636186]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
Гость333
Member

Откуда:
Сообщений: 3683
gumeniuc
В итоге софт записывает данные в order_details с задержкой в 20 секунд, мои данные не записываются

То есть в таблицу order_details данные вставляет и "софт", и ваш триггер?

Ваш триггер плох тем, что если в таблицу orders записывается больше одной записи за одну вставку, то в order_details попадёт только одна запись со случайным row_id из таблицы inserted.

И да, покажите скрипты создания таблиц orders и order_details (со всеми индексами и constraint'ами).
16 дек 12, 10:35    [13638211]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
Гость333
Member

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

+ то, что вы привели, это полный текст триггера? Или вы его упростили?
16 дек 12, 10:36    [13638212]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
gumeniuc
Member

Откуда: md
Сообщений: 133
Гость333
То есть в таблицу order_details данные вставляет и "софт", и ваш триггер?


Да

Гость333
Ваш триггер плох тем, что если в таблицу orders записывается больше одной записи за одну вставку, то в order_details попадёт только одна запись со случайным row_id из таблицы inserted.


Дело в том, что софт может записать за 1 клик только 1 строку в таблицу orders, поэтому я не сомневаюсь, что row_id будет правильным

Гость333
И да, покажите скрипты создания таблиц orders и order_details (со всеми индексами и constraint'ами).


Софт сам создаёт базу с таблицами при установке. Студия выдала мне следующие скрипты создания таблиц:

CREATE TABLE [dbo].[orders](
	[row_id] [int] IDENTITY(1,1) NOT NULL,
	[id] [uniqueidentifier] NOT NULL,
	[pointId] [uniqueidentifier] NOT NULL,
	[service] [varchar](20) NOT NULL,
	[_value] [decimal](18, 2) NOT NULL,
	[_total] [decimal](18, 2) NOT NULL,
	[_account] [varchar](200) NOT NULL,
	[input_date] [datetime] NOT NULL,
	[sent] [bit] NOT NULL,
	[doc_number] [varchar](30) NULL,
 CONSTRAINT [PK_orders] PRIMARY KEY CLUSTERED 
(
	[row_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
 CONSTRAINT [IX_orders] UNIQUE NONCLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[orders] ADD  CONSTRAINT [DF_orders_sent]  DEFAULT ((0)) FOR [sent]
GO


================================

CREATE TABLE [dbo].[order_details](
	[row_id] [bigint] IDENTITY(1,1) NOT NULL,
	[_name] [varchar](50) NULL,
	[_value] [varchar](200) NULL,
	[order_id] [int] NULL,
 CONSTRAINT [PK_order_details] PRIMARY KEY CLUSTERED 
(
	[row_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[order_details]  WITH CHECK ADD  CONSTRAINT [FK_order_details_orders] FOREIGN KEY([order_id])
REFERENCES [dbo].[orders] ([row_id])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[order_details] CHECK CONSTRAINT [FK_order_details_orders]
GO


Гость333
+ то, что вы привели, это полный текст триггера? Или вы его упростили?


Это его полный текст.
16 дек 12, 14:56    [13638702]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
Гость333
Member

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

Как вариант — перед вставкой в order_details "софт" удаляет из order_details данные по заказу :-)

Можно сделать так. Добавляете в триггере "waitfor delay" не перед insert'ом, а после него. Пока триггер висит на waitfor, сделайте выборку из базы:
select top (10) * from order_details with(nolock) order by row_id desc

Так вы увидите, вставилась в триггере ваша запись или нет.

Ну и профайлером можно помониторить команды, выполняемые на сервере. Правда, профайлер не входит в состав Express Edition.

А насчёт того, что
insert into order_details(<надо напесать поля ЯВНО>)

вы когда-нибудь поймёте после наступания на очередные грабли ;-)
16 дек 12, 15:39    [13638858]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
gumeniuc
Member

Откуда: md
Сообщений: 133
Гость333
gumeniuc,

Как вариант — перед вставкой в order_details "софт" удаляет из order_details данные по заказу :-)


Не думаю, как-то неоправданно и нет в этом никакого смысла :-)

Гость333

Можно сделать так. Добавляете в триггере "waitfor delay" не перед insert'ом, а после него. Пока триггер висит на waitfor, сделайте выборку из базы:
select top (10) * from order_details with(nolock) order by row_id desc

Так вы увидите, вставилась в триггере ваша запись или нет.



Делал, во время delay записей никаких нет, а после вставляются данные, которые передаёт софт.


Гость333
А насчёт того, что
insert into order_details(<надо напесать поля ЯВНО>)

вы когда-нибудь поймёте после наступания на очередные грабли ;-)


Завтра проверю, справедливости ради.

Ну а насчёт триггера, возможно я что-то упустил ?! очень уж похоже, что отрабатывает он как FOR, а не AFTER...
16 дек 12, 21:32    [13639853]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
gumeniuc
Ну а насчёт триггера, возможно я что-то упустил ?! очень уж похоже, что отрабатывает он как FOR, а не AFTER...
Феерично!
FOR = AFTER всегда!
16 дек 12, 21:43    [13639907]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
gumeniuc
Member

Откуда: md
Сообщений: 133
iap
FOR = AFTER всегда!


Мда.. понял насколько затупил... Т.е. невозможно создать триггер, который отработает уже после операции insert ?
Да и не вижу логику создавать FOR и AFTER, если они работают идентично.
16 дек 12, 22:05    [13640002]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
gumeniuc
Т.е. невозможно создать триггер, который отработает уже после операции insert ?
Триггер FOR, который одновременно AFTER, срабатывает уже после операции insert.
gumeniuc
Мда.. понял насколько затупил
+1 :-)
16 дек 12, 22:09    [13640013]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
gumeniuc
Member

Откуда: md
Сообщений: 133
alexeyvg
Триггер FOR, который одновременно AFTER, срабатывает уже после операции insert.


В таком случае почему в order_details ничего не пишется ?

Более того, если во время delay я могу в эту самую таблицу спокойно писать, а триггер не в состоянии этого сделать %)

Может у кого есть идеи ?!
16 дек 12, 22:35    [13640087]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
gumeniuc
alexeyvg
Триггер FOR, который одновременно AFTER, срабатывает уже после операции insert.


В таком случае почему в order_details ничего не пишется ?

Более того, если во время delay я могу в эту самую таблицу спокойно писать, а триггер не в состоянии этого сделать %)

Может у кого есть идеи ?!
Идея простая - у вас где то ошибка.

Я вот создал ваши таблицы, создал триггер, вставил запись в таблицу orders - в order_details тоже появилась запись.

Вы хоть триггер-то покажите, который написали.

И покажите код, которым вы его проверили, покажите выборки данных, подтверждающие, что запись не появляется.
16 дек 12, 23:25    [13640205]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
gumeniuc
Member

Откуда: md
Сообщений: 133
В общем не выдержал и поставил 2008 EE. В итоге профайлер показал, что софтина удаляет все детали перед записью. Пытаюсь теперь победить сей недуг.
Всем спасибо за помощь.
17 дек 12, 19:00    [13645307]     Ответить | Цитировать Сообщить модератору
 Re: триггер AFTER INSERT  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
gumeniuc
В итоге профайлер показал, что софтина удаляет все детали перед записью
:-)
17 дек 12, 19:06    [13645329]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить