2011-10-20 16 views
1

これまで試みてきましたが成功しませんでした。クエリに関する私の知識は限られているので、私はそれをここに掲載するほうがいいと思った。元のレコードを見つけ、挿入されていないレコードのみを検索してください

私はIDを持っている学生の数を持って次の構造

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

を持つ学生のテーブルを持って、studentName(SNAME)、状態(「アクティブ」または「アクティブでない」)、更新(新しい学生の場合は「いいえ」、更新された学生の場合は「はい」)と登録日。

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トリガーを持っています。だから私は 'はい'に更新を設定している、次のものを挿入する場合は、既存のレコード '非アクティブ'にする必要があります。

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

私はこのINSERTトリガーを書き、それが動作しますが、新旧両方の挿入されたレコードを活性物質で、それ。元のレコードだけを無効にしたい。また、登録日と新しいフィールドだけが異なるわけではなく、残りは元のレコードと挿入レコードの間で同じです。これを修正するには?ここに私のトリガーがあります

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

答えて

0

あなたは@@アイデンティティを見ましたか?何年か前に私は同じようなものを扱い、@@アイデンティティを使って最後に作成したアイデンティティ値を得ました。基本的に最新のアイデンティティ値を取得し、IDが@@アイデンティティによって返されたもの以外の条件に一致するすべてのレコードを設定します。

ここで識別値ゲッターについての記事を読む: 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 

注:メモリから書き込まれ、テストされていません。

+0

私は最後に挿入されたレコードが解決策を提供しないと思います。'Inserted'テーブルには、元のテーブルと結合して、変更が必要な実際のレコードを見つけるために必要なものすべてがあります。 –

+0

私は通常、トリガーで作業しません。私がアプローチについて考えていたことの詳細については、私の更新された答えを見てください。 – OCary

1
これにあなたのアップデートを変更し

ありがとう:

UPDATE students 
    SET status = 'Inactive' 

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

これは、あなたが更新している行が新たに挿入された行はありませんことを確認します。

+0

質問:どのようにそれが元のレコードを更新することを確認しますか? –

+0

@Thecrocodilehunter - 挿入時に自動生成される 'Id'が新しい行の' id'と一致しないことを確認しているので、これはちょっとした工夫でした。 – JNK

+0

これは私のテスト例では問題なく動作しますが、実際のコードでは逆の動作をします。行は、更新が必要なものではなく、INSERTEDテーブルで更新されます。 –

関連する問題