Найдите оригинальную запись и измените только ту, которая не вставлена - PullRequest
1 голос
/ 20 октября 2011

Я пробовал, но пока не удалось. Поскольку мои знания в запросах ограничены, я подумал, что лучше разместить их здесь.

У меня есть таблица студентов со следующей структурой

create table students(
id int not null primary key identity,
sname varchar(25),
status varchar(25),
renew varchar(15),
enrollment datetime,
)

У меня есть несколько студентов, у которых есть ID, имя студента (имя), статус («активный» или «неактивный»), продление («нет» для нового студента, да «для нового студента) и дата зачисления .

insert into students values('jay','active','no','2010-01-01')
insert into students values('Phil','active','no','2010-01-01')
insert into students values('Cru','active','no','2010-01-01')
insert into students values('slow','active','no','2010-01-01')
insert into students values('true','active','no','2010-01-01')
insert into students values('false','active','no','2010-01-01')

Теперь у меня есть INSERT Trigger, который предполагает отключение старого ученика при его продлении. Поэтому, если я вставлю следующее, для которого установлено обновление «Да», то уже существующая запись должна стать «неактивной».

insert into students values('false','active','yes','2011-01-01')

Я написал этот INSERT Trigger, и он работает, но он активирует старую и новую вставленные записи. Я хочу, чтобы только оригинальная запись была деактивирована. Также не только то, что отличаются только дата регистрации и новые поля, остальные одинаковы между исходной и вставной записями. Как это исправить? Вот мой триггер

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[tr_renew_student]
ON [dbo].students
-- WITH ENCRYPTION
FOR INSERT
-- WITH APPEND
-- NOT FOR REPLICATION
AS
-- insert sql here
if exists(select * from inserted where Renew = 'yes')
BEGIN

UPDATE students 
    SET status = 'Inactive'

    FROM Inserted i
        INNER JOIN students T2
            ON i.sname = T2.sname

END

Обратите внимание, что это близко к моей проблеме. Спасибо enter image description here

Ответы [ 2 ]

1 голос
/ 20 октября 2011

Измените ваше обновление на это:

UPDATE students 
    SET status = 'Inactive'

    FROM Inserted i
        INNER JOIN students T2
            ON i.sname = T2.sname
            AND i.id <> t2.id

Это проверяет, что обновляемая строка НЕ ​​является вновь вставленной строкой.

0 голосов
/ 20 октября 2011

Вы смотрели на @@ identity?Несколько лет назад я имел дело с чем-то похожим и использовал @@ identity, чтобы получить последнее значение идентификатора;в основном, получая последнее значение идентификатора, затем устанавливая все записи, соответствующие критериям, кроме записи с идентификатором, возвращенным через @@ identity.

Подробнее о методах получения значения идентификатора здесь: http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/

Добавлено : Вы правы насчет таблицы inserted.Если вы не хотите / не можете использовать вставленную таблицу, ваш триггер может выглядеть примерно так:

SELECT @@identity //  <- this gets the last identity value inserted.

UPDATE students
SET status = 'Inactive'
WHERE students.name = (SELECT name FROM students WHERE id = @@identity)
  AND id <> @@identity

Примечание: записано из памяти и не проверено.

...