2012-06-13 24 views
27

従業員の行を挿入するテーブルがありますが、次回は行を挿入したいときにその従業員のデータを再度挿入する必要はありません新しい列を作成しない場合は、必要な列が更新されます。SQL Server 2005でupsert(更新または挿入)する方法

SQL Server 2005でこれを行うにはどうすればいいですか?

私は、JSP

私のクエリは、それが初めての場合は、それを行うにどのよう

を更新存在するならば、他のデータベースに挿入し

String sql="insert into table1(id,name,itemname,itemcatName,itemQty)values('val1','val2','val3','val4','val5')"; 

あるを使用していますか?

+1

** MERGE節**を使用すると、それと一緒にユーザーの詳細を示す一時表が表示されますか?これはいい? –

+0

Sakhile - そうです - 答えはどこですか?答えはどこですか? –

+0

'MERGE'はこのユースケースには適していますが、SQL Server 2008でのみ導入されたことに注意してください(おそらくOPはまだ6年後の2005年をまだ使用していません)。 –

答えて

32

存在するかどうかを確認してください:

IF NOT EXISTS (SELECT * FROM dbo.Employee WHERE ID = @SomeID) 

    INSERT INTO dbo.Employee(Col1, ..., ColN) 
    VALUES(Val1, .., ValN) 

ELSE 

    UPDATE dbo.Employee 
    SET Col1 = Val1, Col2 = Val2, ...., ColN = ValN 
    WHERE ID = @SomeID 

あなたは簡単にストアドプロシージャにこれをラップし、ちょうど(C#または使用しているものは何でものようなプログラミング言語から例えば)外部からそのストアドプロシージャを呼び出すことができます。

更新:あなただけ(なんとか - しかし、実際には非常に有用ではない) - 1つの長い文字列で、この文全体を記述するか、またはストアドプロシージャにそれをラップすることができます:ちょうどその

CREATE PROCEDURE dbo.InsertOrUdpateEmployee 
     @ID INT, 
     @Name VARCHAR(50), 
     @ItemName VARCHAR(50), 
     @ItemCatName VARCHAR(50), 
     @ItemQty DECIMAL(15,2) 
AS BEGIN 
    IF NOT EXISTS (SELECT * FROM dbo.Table1 WHERE ID = @ID) 
     INSERT INTO dbo.Table1(ID, Name, ItemName, ItemCatName, ItemQty) 
     VALUES(@ID, @Name, @ItemName, @ItemCatName, @ItemQty) 
    ELSE 
     UPDATE dbo.Table1 
     SET Name = @Name, 
      ItemName = @ItemName, 
      ItemCatName = @ItemCatName, 
      ItemQty = @ItemQty 
     WHERE ID = @ID 
END 

+0

上記のコードを上記のSQL文字列に記述するか、トリガーまたはプロシージャを作成する必要があります。 – ybc126

+1

単一文字列で書くと、 のようになります。String sql = "IF NOT EXIST(SELECT * FROM Employee WHERE ID = @ someid)INSERT INTO EMPLOYEE(col1、...、colN)の値(val1、..、valN)ELSE UPDATE EMPLOYEE SET col1 = val1、col2 = val2、...、colN = valN WHERE ID = @ someID " これは動作しますか? – ybc126

+0

@ ybc126:SQLに必要なスペースがある場合 - はい。しかし、そのようなものは、間違いなく**間違いありません**!これをストアドプロシージャに入れて(ORMを使ってこれを処理する)** **もっと良い** –

1

テーブルのINSTEAD OF INSERTトリガーを使用すると、行が存在するかどうかをチェックし、行が存在するかどうかによって更新/挿入を行うことができます。 MSDN here上でSQL Serverの2000+のためにこれを行う方法の例があります:

CREATE TRIGGER IO_Trig_INS_Employee ON Employee 
INSTEAD OF INSERT 
AS 
BEGIN 
SET NOCOUNT ON 
-- Check for duplicate Person. If no duplicate, do an insert. 
IF (NOT EXISTS (SELECT P.SSN 
     FROM Person P, inserted I 
     WHERE P.SSN = I.SSN)) 
    INSERT INTO Person 
     SELECT SSN,Name,Address,Birthdate 
     FROM inserted 
ELSE 
-- Log attempt to insert duplicate Person row in PersonDuplicates table. 
    INSERT INTO PersonDuplicates 
     SELECT SSN,Name,Address,Birthdate,SUSER_SNAME(),GETDATE() 
     FROM inserted 
-- Check for duplicate Employee. If no duplicate, do an insert. 
IF (NOT EXISTS (SELECT E.SSN 
     FROM EmployeeTable E, inserted 
     WHERE E.SSN = inserted.SSN)) 
    INSERT INTO EmployeeTable 
     SELECT EmployeeID,SSN, Department, Salary 
     FROM inserted 
ELSE 
--If duplicate, change to UPDATE so that there will not 
--be a duplicate key violation error. 
    UPDATE EmployeeTable 
     SET EmployeeID = I.EmployeeID, 
      Department = I.Department, 
      Salary = I.Salary 
    FROM EmployeeTable E, inserted I 
    WHERE E.SSN = I.SSN 
END 
11

あなたは、行が挿入または更新する必要があるかどうかを確認する@@ROWCOUNTを使用することができます。この場合は

update table1 
set name = 'val2', itemname = 'val3', itemcatName = 'val4', itemQty = 'val5' 
where id = 'val1' 
if @@ROWCOUNT = 0 
insert into table1(id, name, itemname, itemcatName, itemQty) 
values('val1', 'val2', 'val3', 'val4', 'val5') 

場合更新が失敗すると、新しい行が挿入されます

4

(私の答えは以下ですが、それ以降はより良い質問があります)&答えはInsert into a MySQL table or update if existsです

あなたは行が存在するかどうかをチェックして、INSERTまたはUPDATEが、これは、あなたが1つではなく、2つのSQL操作を実行することが保証されますができます。

  1. チェックを行は
  2. 挿入または更新行
  3. が存在する場合

より良い解決策は、常に最初に更新することで、何行が更新されなかった場合は、そのようにように、INSERTを実行します。

update table1 
set name = 'val2', itemname = 'val3', itemcatName = 'val4', itemQty = 'val5' 
where id = 'val1' 

if @@ROWCOUNT = 0 
    insert into table1(id, name, itemname, itemcatName, itemQty) 
    values('val1', 'val2', 'val3', 'val4', 'val5') 

これは、行がすでに存在するかどうかに応じて、1つのSQL操作または2つのSQL操作を行います。

パフォーマンスが実際に問題になる場合、操作がINSERTまたはUPDATEの可能性が高いかどうかを判断する必要があります。 UPDATEの方が一般的な場合は、上記を行います。 INSERTの方が一般的であれば、逆にすることもできますが、エラー処理を追加する必要があります。

BEGIN TRY 
    insert into table1(id, name, itemname, itemcatName, itemQty) 
    values('val1', 'val2', 'val3', 'val4', 'val5') 
END TRY 
BEGIN CATCH 
    update table1 
    set name = 'val2', itemname = 'val3', itemcatName = 'val4', itemQty = 'val5' 
    where id = 'val1' 
END CATCH 

あなたがUPDATEまたはINSERTを行う必要がある場合、あなたは、単一のトランザクション内で2つの操作を行う必要が本当にある特定のことができます。理論的には、最初のUPDATEまたはINSERT(またはEXISTSチェック)の直後、次のINSERT/UPDATEステートメントの前に、データベースが変更されていて、2番目のステートメントが失敗する可能性があります。これは非常に稀であり、トランザクションのオーバーヘッドはそれに値するものではないかもしれません。

また、MERGEという単一のSQL操作を使用してINSERTまたはUPDATEを実行することもできますが、これはおそらくこの1行操作の過剰な操作です。

SQL transaction statementsrace conditions、​​についてお読みください。

+0

あなたが言及する質問へのリンクは、このスレッドがON DUPLICATE KEY UPDATEオプションを持たないSQL Serverに関するMySqlに固有のものです。どの回答が意味するのか、これがあなたの間違いなのかを明確にすることができますか? –

関連する問題