63

従業員の行を挿入するテーブルがありますが、次に行を挿入するときに、その従業員のデータを再度挿入したくないので、必要な列が存在する場合は更新し、そうでない場合は新しい行を作成します

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

私はjspを使用しています

私の質問は

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

初めての場合はデータベースに挿入し、存在する場合は更新します

実行する方法?

4

5 に答える 5

81

存在を確認してみてください:

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.InsertOrUpdateEmployee
       @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

次に、ADO.NETコードからそのストアドプロシージャを呼び出すだけです。

于 2012-06-13T08:02:14.087 に答える
68

@@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')

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

于 2013-03-13T21:25:35.867 に答える
17

行が存在するかどうかを確認してから、INSERT または UPDATE を実行できますが、これにより、1 つではなく 2 つの SQL 操作を実行することが保証されます。

  1. 行が存在するかどうかを調べる
  2. 行の挿入または更新

より良い解決策は、常に最初に UPDATE を行い、行が更新されていない場合は、次のように 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 を実行する必要があるかどうかを確実にするには、1 つの TRANSACTION 内で 2 つの操作を実行する必要があります。理論的には、最初の UPDATE または INSERT (または EXISTS チェック) の直後であるが、次の INSERT/UPDATE ステートメントの前に、データベースが変更され、2 番目のステートメントがいずれにせよ失敗する可能性があります。これは非常にまれであり、トランザクションのオーバーヘッドはそれに値しない場合があります。

別の方法として、MERGE と呼ばれる単一の SQL 操作を使用して INSERT または UPDATE を実行することもできますが、これも、この 1 行の操作にはおそらくやり過ぎです。

SQL トランザクション ステートメント競合状態SQL MERGE ステートメントについて読むことを検討してください。

于 2015-01-16T17:49:57.920 に答える
3

テーブルのトリガーを使用してこれを行うことができます。これINSTEAD OF INSERTは、行の存在をチェックし、既に存在するかどうかに応じて更新/挿入します。MSDN の 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
于 2012-06-13T08:21:44.873 に答える