2012-03-30 7 views
0

empテーブルにプライマリキーを持つ一意の行があります。SQL Serverで問題を更新または挿入しますか?

select * from EMP E; 

は今、私は次のようにempテーブルのバックアップを取るemp_backupテーブルを作成しました。

insert into emp_backup 
select * from emp e 
where not exists (select EMPNO from emp_backup E1 where E1.EMPNO=e.EMPNO); 

上記のクエリに成功コピーempからemp_backupのすべての行と再度クエリの上に実行すると、それが次の実行にempからemp_backupテーブルに既存の行をコピーしないことを確認してください。

今私の問題は、empテーブルのレコードを更新して上記のクエリを実行しようとすると、私にはエラーprimary key violationが除外されます。

などです。

update EMP 
set JOB='worker' 
where EMPNO=14; 

私はテーブルをemp_backupするempno 14でレコードをコピーした後empテーブルを更新します。

私が実行したときinsert into emp_backup....クエリこの更新プログラムの変更を希望する場合は、emp_backupテーブルに再選択する必要があります。

上記のクエリを変更して、既存の主キーを持つ更新された行をempからemp_backupにコピーするにはどうすればよいですか。

私の質問がはっきりしていることを願って、私がそれを改善する方法を教えてください。

+0

あなたはemp_backup –

+0

で一意キーまたは主キーとして、他の列を定義している@SathyaNarayanan Iまし両方 'emp'と' emp_backup'テーブルの主キーとしてのみ 'empno' 。 –

+1

なぜバックアップを使用しないのですか?あなたはオプションのための完全なだけでなく差分を使用することができます... –

答えて

0

を削除します。これにより、同じempレコードを2回挿入することができなくなります。

あなたはあなたの「バックアップ」の計画を再考する必要がある - あなたは正確にemp表内のすべてのレコードの変更のすべてのバージョンの走行監査

  • にemp表のミラーを

    1. をしたいですか? 1については

    • ドロップemp_backupテーブルの主キー。これにより、複製されたempレコードをコピーすることができます。 emp_backupテーブルに冪等が必要な場合は、新しいサロゲートPKを作成することができます。(コラムこと

      insert into emp_backup 
      select * from emp e 
      where exists 
          (select EMPNO 
          from emp_backup E1 
          where E1.EMPNO=e.EMPNO 
          and 
          (e1.othercolumn1 <> e.othercolumn1 
          or e1.othercolumn2 <> e.othercolumn2 
          ... 
          ) 
      ); . 
      

      注意:emp_backup_id int identity(1,1)、おそらく新しいCURRENT_TIMESTAMP不履行列には、最新の

    あなたのPKを落とした後、更新されたレコードは次のように「バックアップ」することが可能であるかを決定する際に役立ちます特定の種類の直接比較することはできません)

    2については

    、あなたはemp_bakテーブル内の既存のレコードを更新する必要があります:

    update eb 
    set eb.othercolumn1 = e.othercolumn1, 
        eb.othercolumn2 = e.othercolumn2 
    from emp_backup eb 
        inner join emp e on eb.empno = e.empno 
    where 
        eb.othercolumn1 <> e.othercolumn1 
        or eb.othercolumn2 <> e.othercolumn2 
        ... 
    ); . 
    

    しかし、あなたのテーブルのミラーリングが質問を頼む、毎回バックアップをしたい、ちょうどあなたの既存のemp_backupテーブルをドロップしない理由:

    insert into emp_backup 
    select * from emp e 
    

  • +0

    毎回100万を超えるレコードを含むバックアップテーブルを削除できません。 –

    +0

    その場合、@ Karlが提案するようにトリガーを使用するか、そうでなければあなたのデータをOMGPoniesのコメントのようなバックアップに委ねてください。 – StuartLC

    1

    すべての変更を収集するためには、履歴(または監査)テーブルが必要です。あなたのテーブルにtrigerを作成し、レコードを書き出して、アクティビティタイムフィールドに各変更の履歴テーブルを含めます。アクティビティ時間フィールドが最後のバックアップクエリよりも大きい場合は、履歴テーブルから選択します。

    thizsは、すべての更新、挿入を収集することができますし、あなたがまた、EMPNOのテーブルの上にテーブルのPKを作成したことを、あなたはemp_backupテーブルを作成したときと思われ

    0

    SQL Server 2008を使用しているので、MERGEコマンドを使用できます。

    この1つのコマンドは、バックアップテーブルに存在しないレコードを追加し、存在する場合に一致するように更新します。

    Here's an example from MSDNは:

    MERGE emp_backup AS T 
    USING emp AS S 
    ON (T.EMPNO = S.EMPNO) 
    WHEN NOT MATCHED BY TARGET 
        THEN INSERT(EMPNO, JOB) VALUES(S.EMPNO, S.JOB) 
    WHEN MATCHED 
        THEN UPDATE SET T.JOB = S.JOB 
    
    関連する問題