Модераторы: Akina
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> trigger for insert, удваивается значение 
V
    Опции темы
lBugl
Дата 17.3.2010, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 18.8.2009

Репутация: нет
Всего: 2



есть 2 таблицы:
User -- int PK id,   varchar(20) User, int kol
User_copy -- in PK id, varchar(20) Name, int kol

пишу триггер на insert в User. при добавлении в User проверяю если такой записи нет в User_copy, то добовляю её туда. Если Запись в User_copy с таким именем уже существует, то обновляю в User_copy поле kol (добавляю новое значение User_copy.kol + User.kol).
проблема в том, что заноситься удвоенное значение User.kol, объясните пожалуйста почему

trigger:
Код

CREATE  TRIGGER u_ins ON [dbo].[User] 
    FOR INSERT
AS
    declare @id int
    declare @user varchar(20)
    declare @kol int
    declare cur_ins    cursor for select [ID], [User], kol from inserted
    open cur_ins
    while ( 0 = 0)
    begin
        fetch next from cur_ins into @id, @user, @kol
        if (not exists (select * from User_copy where Name = @user) ) begin
            insert into User_copy (Name, kol) values (@user, @kol)
        end
        else begin
            update User_copy set kol = (kol + @kol) where Name = @user             
        end
        if (@@fetch_status <>0 ) break
    end
    close cur_ins
    deallocate cur_ins


и так после запроса

Код

insert into [User] ([User], kol) values('user1', 3)

таблица User содержит:
1 -- user1 -- 3
Таблица User_copy
1 -- user1 -- 6

Код

insert into [User] ([User], kol) values('user1', 1)

таблица User содержит:
1 -- user1 -- 3
1 -- user1 -- 1
Таблица User_copy
1 -- user1 -- 8

где еррор?...

=))) пока писал пост исправил ошибку
в цикле перед fetch next добавил  set @kol = 0. всё работает правильно теперь.
только всё равно не очень понятно, почему значение удваивалось. мб это из-за того что триггер выполняется после insert`a но не очень понятно как это влияет на таблицу inserted.  в общем в чём тут дело?=)


PM MAIL   Вверх
Akina
Дата 17.3.2010, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 25
Всего: 454



Код

    open cur_ins
    fetch next from cur_ins into @id, @user, @kol
    while ( @@fetch_status = 0)
    begin
        if (not exists (select * from User_copy where Name = @user) ) begin
            insert into User_copy (Name, kol) values (@user, @kol)
        end
        else begin
            update User_copy set kol = (kol + @kol) where Name = @user             
        end
        fetch next from cur_ins into @id, @user, @kol
    end


Добавлено через 2 минуты и 29 секунд
или 
Код

    open cur_ins
    while ( 0 = 0)
    begin
        fetch next from cur_ins into @id, @user, @kol
        if (@@fetch_status <>0 ) break
        if (not exists (select * from User_copy where Name = @user) ) begin
            insert into User_copy (Name, kol) values (@user, @kol)
        end
        else begin
            update User_copy set kol = (kol + @kol) where Name = @user             
        end
    end


Добавлено через 3 минуты и 16 секунд
Цитата(lBugl @  17.3.2010,  11:04 Найти цитируемый пост)
в цикле перед fetch next добавил  set @kol = 0. всё работает правильно теперь.

Математически - правильно. Логически - более чем неправильно.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
lBugl
Дата 17.3.2010, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 18.8.2009

Репутация: нет
Всего: 2



кажется въехал... спасиб.
вижу, что у меня цикл делал один лишний круг. сначала пробовал читать потом добавлял. и потом только проверял правильно ли прочитал...
кстати это не упрощается? мб можно без курсора сделать
PM MAIL   Вверх
skyboy
Дата 17.3.2010, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 2
Всего: 260




M
skyboy
Перенесено их баз данных

PM MAIL   Вверх
Akina
Дата 17.3.2010, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 25
Всего: 454



Цитата(lBugl @  17.3.2010,  12:06 Найти цитируемый пост)
мб можно без курсора сделать 

Конечно можно... просто выполни два запроса, сначала типа
Код

update user_copy
set user_copy.kol = user_copy.kol + inserted.kol
from user_copy 
inner join inserted
on user_copy.name = inserted.user
а потом 
Код

insert into user_copy (name, kol)
select inserted.user, inserted.kol 
from inserted
right join user_copy
on user_copy.name = inserted.user
where user_copy.name is null

ЗЫ. ПисАл наскоро, мог ошибиться - но идея, думаю, понятна.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
lBugl
Дата 17.3.2010, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 18.8.2009

Репутация: нет
Всего: 2



да, идея понятна.

в новом варианте выполняется два запроса.
в моём случае, тоже два, но в цикле...
отсюда вопрос:

таблица inserted содержит новые записи (которые должны добавиться в исходную таблицу)
может ли inserted содержать более 1 записи? ведь запрос insert куда-то, что-то добавляет только одну запись, и на каждый такой запрос, я так понимаю, будет вызваться триггер на инсерт, где и проверяется содержание inserted.

зы: хочется понять какой вариант оптимальней и правильно ли я себе представляю работу триггера и inserted
PM MAIL   Вверх
Akina
Дата 17.3.2010, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 25
Всего: 454



Цитата(lBugl @  17.3.2010,  13:00 Найти цитируемый пост)
может ли inserted содержать более 1 записи?

Если ты вставляешь не по одной записи, а несколько - то и в таблице будет несколько строк.
На один insert триггер вызывается 1 раз, и в inserted ему передаются все вставляемые строки.

Добавлено через 7 минут и 14 секунд
А вообще вместо того, чтобы задавать такие вопросы, лучше один раз вдумчиво прочитать документацию.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
lBugl
Дата 17.3.2010, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 18.8.2009

Репутация: нет
Всего: 2



да, посмотрел что инсертом можно вставлять сразу несколько строк. лично как-то не доводилось это делать.
ещё раз спасиб за помощь.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "MS SQL"
Akina

Akina

Запрещается!

Публиковать ссылки и обсуждать взлом чего бы то ни было.

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы составления неспецифических запросов рассматриваются здесь
  • Используйте теги [code=sql][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, Akina.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MS SQL Server | Следующая тема »


 




[ Время генерации скрипта: 0.0610 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.