Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Поведение триггера AFTER INSERT,DELETE,UPDATE / 25 сообщений из 26, страница 1 из 2
05.04.2018, 15:19
    #39626166
PisarevskiyRE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
Добрый день, коллеги.

Второй день ломаю голову по поводу вот такой задачи -
Есть таблица orders, триггер натравлен на эту таблицу.
Сценарий такой - про добавлении строки в заказы пишется лог в таблицу orders_log и insert двух строк
в вспомогательную таблицу.

Вопрос к знатокам - почему иногда примерно 1000 к 1 в таблице inserted пропадают значения???

К примеру -
1. Создаем заказ (insert into orders)
2. Триггер агрится и начинает выполнение.
3. Достаем значение из inserted и вставляем в лог. Ок.
4. Достаем значение из inserted и вставляем в вспомогательную. Не ок. Строка не создается.

Для понимаю вставлю запрос.

Код: sql
1.
2.
3.
4.
select o.id, dbo.DateToDateStr( o.CREATIONDATETIME), vg.id, vg.* from orders o
left join VG_FIELD_VALUES vg on vg.REF = o.id and FIELDID = 290 
where  CREATIONDATETIME >= 43195.4747560069 
order by o.CREATIONDATETIME desc, o.ID desc



2611730 05.04.2018 15:10:46 84413792 84413792 NewOrder 2611730 0 1 290
2611729 05.04.2018 15:10:45 84413763 84413763 NewOrder 2611729 0 1 290
2611728 05.04.2018 15:10:42 84413735 84413735 NewOrder 2611728 0 1 290
2611726 05.04.2018 15:10:39 NULL NULL NULL NULL NULL NULL NULL
2611727 05.04.2018 15:10:39 84413684 84413684 NewOrder 2611727 0 1 290
2611725 05.04.2018 15:10:36 84413653 84413653 NewOrder 2611725 0 1 290
2611724 05.04.2018 15:10:34 84413625 84413625 NewOrder 2611724 0 1 290

Тело триггера выглядит вот так -

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
SET NOCOUNT ON;
   DECLARE @I BIT = 0, @D BIT = 0, @U BIT = 0, @insert_id bigint = 0, @insert_clientid bigint = 0
    IF EXISTS (SELECT TOP 1 * FROM INSERTED)
    BEGIN
        IF EXISTS (SELECT TOP 1 * FROM DELETED)
        BEGIN    
            SET @U = 1
        END
        ELSE
        BEGIN
            SET @I = 1
        END
    END
    ELSE
    BEGIN
        SET @D = 1
    END  
    IF @D = 1
    BEGIN
        INSERT INTO dbo.ORDERS_log (ChangedID, ChangedOperation)
        SELECT DISTINCT d.ID, 'D'
        FROM deleted d
    END  
    IF @I = 1
    BEGIN
        SELECT @insert_id = i.ID, @insert_clientid = i.clientid FROM inserted i
        INSERT INTO dbo.ORDERS_log (ChangedID, ChangedOperation)
        SELECT @insert_id, 'I'

		insert into VG_FIELD_VALUES (FORMNAME, REF, SVALUE, ENABLED, FIELDID)    
		VALUES
		('NewOrder',@insert_id,CAST(CAST(ROUND(dbo.GetMaxAutoSum(@insert_id), 0) AS VARCHAR(255)) AS TEXT),1,290),
		('NewOrder',@insert_id,CAST(CAST(@insert_clientid ^ 0xdeadee AS VARCHAR(255)) AS TEXT),1,286)
    END 
    IF @U = 1
    BEGIN
        INSERT INTO dbo.ORDERS_log (ChangedID, ChangedOperation)
        SELECT DISTINCT i.ID, 'U'
        FROM inserted i
    END



Определяется тип произведенной операции и производятся действия.
Вот чего я не понимаю почему insert в ORDERS_log выполняется всегда, а следующая вставка 1 к 1000 заканчивается нулами???
Нагрузка на сервер довольно таки большая.
...
Рейтинг: 0 / 0
05.04.2018, 15:29
    #39626168
Maxx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
inserted может содержать больше чем 1 запись
...
Рейтинг: 0 / 0
05.04.2018, 15:45
    #39626177
PisarevskiyRE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
Maxx, не в этом дело. До этого было 3 отдельные вставки без переменных, напрямую из таблицы inserted.
...
Рейтинг: 0 / 0
05.04.2018, 16:10
    #39626199
Гигабайт Мегабайтович Килобайтов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
ну не волшебство же происходит ))
отсюда два варианта : либо в @insert_id оказывается null, либо в @insert_id оказывается не тот id заказа который вы ожидаете ))
а это может получиться из этого
Код: sql
1.
SELECT @insert_id = i.ID, @insert_clientid = i.clientid FROM inserted i
...
Рейтинг: 0 / 0
05.04.2018, 16:49
    #39626227
PisarevskiyRE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
Гигабайт Мегабайтович Килобайтов, я из-за этого тему и создал.

я пробовал еще 2 варианта


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
        INSERT INTO dbo.ORDERS_log (ChangedID, ChangedOperation)
        SELECT i.id, 'I' from inserted i

        insert into VG_FIELD_VALUES (FORMNAME, REF, SVALUE, ENABLED, FIELDID)    
	select 'NewOrder', i.id,CAST(CAST(ROUND(dbo.GetMaxAutoSum(@insert_id), 0) AS VARCHAR(255)) AS TEXT),1,290 from inserted i

        insert into VG_FIELD_VALUES (FORMNAME, REF, SVALUE, ENABLED, FIELDID)    
	select  'NewOrder',i.id ,CAST(CAST(i.client_id ^ 0xdeadee AS VARCHAR(255)) AS TEXT),1,286)



Был еще union но он вел себя так же.
...
Рейтинг: 0 / 0
05.04.2018, 16:53
    #39626232
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
PisarevskiyRE,

Мне одному кажется странным, что эти данные вставляются
Код: sql
1.
('NewOrder',@insert_id,CAST(CAST(ROUND(dbo.GetMaxAutoSum(@insert_id), 0) AS VARCHAR(255)) AS TEXT),1,290),


а эти нет
Код: sql
1.
('NewOrder',@insert_id,CAST(CAST(@insert_clientid ^ 0xdeadee AS VARCHAR(255)) AS TEXT),1,286)
...
Рейтинг: 0 / 0
05.04.2018, 16:57
    #39626237
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
PisarevskiyRE,

а откуда уверенность, что пустые - это не update операции?
...
Рейтинг: 0 / 0
05.04.2018, 17:17
    #39626249
PisarevskiyRE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
blonduser, from inserted строка существует и записывается, следующие 2 оператора пропускается. Повторяюсь это случай 1/1000. И когда это проходит по времени вставки видно что транзакция ожидает чего - то.
...
Рейтинг: 0 / 0
05.04.2018, 17:22
    #39626251
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
PisarevskiyRE,

В триггере они у вас выглядят так
Код: sql
1.
2.
3.
4.
		insert into VG_FIELD_VALUES (FORMNAME, REF, SVALUE, ENABLED, FIELDID)    
		VALUES
		('NewOrder',@insert_id,CAST(CAST(ROUND(dbo.GetMaxAutoSum(@insert_id), 0) AS VARCHAR(255)) AS TEXT),1,290),
		('NewOrder',@insert_id,CAST(CAST(@insert_clientid ^ 0xdeadee AS VARCHAR(255)) AS TEXT),1,286)
...
Рейтинг: 0 / 0
05.04.2018, 17:22
    #39626253
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
blonduser,
Что должно пропустится?
...
Рейтинг: 0 / 0
05.04.2018, 17:29
    #39626259
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
а покажите скрипт вашей таблички VG_FIELD_VALUES
...
Рейтинг: 0 / 0
05.04.2018, 17:43
    #39626272
PisarevskiyRE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
Konst_One, REATE TABLE [dbo].[VG_FIELD_VALUES](
[ID] [bigint] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[FORMNAME] [varchar](500) NULL,
[REF] [int] NULL,
[SVALUE] [text] NULL,
[ENABLED] [smallint] NULL,
[FIELDID] [int] NULL,
CONSTRAINT [PK__VG_FIELD_VALUES__3A379A64] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [DataFiles]
) ON [DataFiles] TEXTIMAGE_ON [DataFiles]
GO

ALTER TABLE [dbo].[VG_FIELD_VALUES] ADD CONSTRAINT [DF__VG_FIELD___ENABL__3B2BBE9D] DEFAULT ((1)) FOR [ENABLED]
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Ссылка на Vg_Fields.Id' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'VG_FIELD_VALUES', @level2type=N'COLUMN',@level2name=N'FIELDID'
GO
...
Рейтинг: 0 / 0
05.04.2018, 17:48
    #39626286
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
простите, а какая версия у вас сервера?

Код: sql
1.
select @@version
...
Рейтинг: 0 / 0
05.04.2018, 17:49
    #39626288
PisarevskiyRE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
Konst_One,
Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64) Jun 17 2011 00:54:03 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: )
...
Рейтинг: 0 / 0
05.04.2018, 17:52
    #39626290
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
вы делаете неверные выводы, потому что анализируете неверный запрос:

Код: sql
1.
2.
3.
4.
5.
6.
7.
select 
   o.id, 
   dbo.DateToDateStr( o.CREATIONDATETIME), 
   vg.id, vg.* 
from orders o left join VG_FIELD_VALUES vg on vg.REF = o.id and FIELDID = 290 
where  CREATIONDATETIME >= 43195.4747560069 
order by o.CREATIONDATETIME desc, o.ID desc



в табличке VG_FIELD_VALUES нет никакой записи с выделенным вами ID
...
Рейтинг: 0 / 0
05.04.2018, 18:00
    #39626303
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
а это вы так ищите что нет записи в этой табличке. тогда отбой

зы
вы уверены что у вас удаление не происходит?
...
Рейтинг: 0 / 0
05.04.2018, 18:05
    #39626310
PisarevskiyRE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
Konst_One, дык я выделил просто для наглядности в скрине.
Самое простое объяснение идет подряд 3 inserta из inserted.
1, 2, ..,56,..509,..840,.. и рамдомно не пишется, причем если смотреть по id она должна была вставиться гооораздо раньше.

INSERT INTO dbo.ORDERS_log (ChangedID, ChangedOperation)
SELECT @insert_id, 'I'

insert into VG_FIELD_VALUES (FORMNAME, REF, SVALUE, ENABLED, FIELDID)
VALUES
('NewOrder',@insert_id,CAST(CAST(ROUND(dbo.GetMaxAutoSum(@insert_id), 0) AS VARCHAR(255)) AS TEXT),1,290),
('NewOrder',@insert_id,CAST(CAST(@insert_clientid ^ 0xdeadee AS VARCHAR(255)) AS TEXT),1,286)

-- можно так можно через union all можно разбить на 2 отдельных, сути не меняет записи после 1 операции не создаются
...
Рейтинг: 0 / 0
05.04.2018, 18:09
    #39626315
PisarevskiyRE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
PisarevskiyRE, извиняюсь за фото. В общем случаи получается такая картина -
...
Рейтинг: 0 / 0
05.04.2018, 19:44
    #39626351
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
PisarevskiyRE,

Что возвращает функция dbo.GetMaxAutoSum(@insert_id) ?
Может в ней ошибка?
...
Рейтинг: 0 / 0
05.04.2018, 19:45
    #39626353
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
PisarevskiyREPisarevskiyRE, извиняюсь за фото. В общем случаи получается такая картина -
Что вы гадаете с своими запутанными значениями? Кто так отлаживает???

Навставляйте отладочных селектов в триггер, и потом вставляйте в Order, сразу всё увидите.
...
Рейтинг: 0 / 0
05.04.2018, 20:37
    #39626384
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
PisarevskiyRE,

1. Никаких переменных в триггере! Ну, разве что переменную с обозначением команда, для которой вызван триггер.
2. С inserted и deleted работать как с таблицами, а не источниками скалярных значений.
3. Не применять @@ROWCOUNT на входе триггера. Только EXISTS(SELECT * FROM inserted UNION ALL SELECT * FROM deleted).
Это на случай, если таблицу будут использовать в MERGE.
4. Забыть о типе TEXT. Вместо него - VARCHAR(MAX).
5. Неплохо бы логгировать только данные, которые изменились.
Хорошо в этом деле зарекомендовала себя конструкция FROM inserted i FULL JOIN deleted d ON i.ID=d.ID WHERE NOT EXISTS(SELECT i.Field1, ... , i.FieldN INTERSECT SELECT d.Field1, ... , d.FieldN),
где ID - первичный ключ.
6. Логгировать можно только из deleted, так как inserted и так лежит в таблице.

Всё настолько просто, что непонятно, что тут можно отлаживать.
...
Рейтинг: 0 / 0
06.04.2018, 10:19
    #39626600
StarikNavy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
PisarevskiyRE,
что вернет запрос?

Код: sql
1.
select * from orders_log where changedID= 2593660
...
Рейтинг: 0 / 0
06.04.2018, 17:10
    #39626933
PisarevskiyRE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
blonduser, функция возвращает число int.

alexeyvg, спасибо за совет, но это нельзя осуществить так как база прода, на стейджах повторить не давалось.

iap, спасибо, запомнил.

StarikNavy, приложил скрин.

***************************

Проблема решена.
Оказалось все намного тривиальнее.
Строки удаляет сервис после срабатывания триггера обычным delete.
Чудес не бывает. Отменил вызов команды Рен-ТВ :)
...
Рейтинг: 0 / 0
14.04.2018, 14:20
    #39630235
04cf9f9576a6f15
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
iap1. Никаких переменных в триггере! Ну, разве что переменную с обозначением команда, для которой вызван триггер.Почему?

#Хэш=
...
Рейтинг: 0 / 0
14.04.2018, 15:36
    #39630256
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поведение триггера AFTER INSERT,DELETE,UPDATE
04cf9f9576a6f15iap1. Никаких переменных в триггере! Ну, разве что переменную с обозначением команда, для которой вызван триггер.Почему?

#Хэш=Потому что в скалярную переменную можно поместить только одно значение
(обычно мы это и наблюдаем в триггерах новичков),
в то время как inserted и deleted - это таблицы с миллионами строк! (Специально утрирую).
Скалярная переменная провоцирует новичка писать совершенно некорректный код
для обработки таблиц inserted и deleted.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Поведение триггера AFTER INSERT,DELETE,UPDATE / 25 сообщений из 26, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]