SQL Select : 업데이트가 존재하는 경우 업데이트, 그렇지 않은 경우 삽입 - 날짜 부품 비교?

StackOverflow https://stackoverflow.com/questions/340366

  •  19-08-2019
  •  | 
  •  

문제

다음 필드로 데이터베이스에서 레코드를 업데이트해야합니다.

[ID] int (AutoIncr. PK)
[ScorerID] int
[Score] int
[DateCreated] smalldatetime

오늘 날짜에 대한 기록이 존재하는 경우 (시간이 아닌 날짜 부분 만 확인해야 함) 주어진 득점자 인 경우이 사람과 오늘의 점수 값을 업데이트하고 싶습니다. 득점자에게 오늘 기록이 없다면 새로운 기록을 만들고 싶습니다.

나는 이것을 단일 (이것이 가능합니까?) SQL 문에 이것을 넣는 방법을 알아 내려고 회색 머리카락을 얻고 있습니다. 그건 그렇고 나는 MSSQL 데이터베이스를 사용하고 있습니다. ExecuteNonQuery() 쿼리를 발행하는 방법.

도움이 되었습니까?

해결책

IF EXISTS (SELECT NULL FROM MyTable WHERE ScorerID = @Blah AND CONVERT(VARCHAR, DateCreated, 101) = CONVERT(VARCHAR, GETDATE(), 101))
    UPDATE MyTable SET blah blah blah
ELSE
    INSERT INTO MyTable blah blah blah

다른 팁

다른 사람들은 2005 년 (및 이전) 호환 T-SQL/orproaches를 다루었습니다. SQL Server 2008과 함께 일할만큼 운이 좋으면 새로운 병합 (때로는 Upsert라고도 함)을 활용할 수 있다고 덧붙였습니다.

더 설명하는 블로그 항목이나 기사를 찾는 데 어려움을 겪었지만 오히려 이것을 찾았습니다. (1) 유용한 항목. 공식 MSDN 항목은입니다 (2) 여기.

(1) [http://www.sqlservercurry.com/2008/05/sql-server-2008-merge-statement.html
(2) [http://msdn.microsoft.com/en-us/library/bb510625.aspx

CREATE PROCEDURE InsertOrUpdateScorer(@ScorerID INT, @Score INT)
AS
BEGIN
  IF EXISTS (
    SELECT 1 
    FROM Scorer 
    WHERE ScorerID = @ScorerID AND DATEDIFF(dd, GETDATE(), DateCreated) = 0
  )
  BEGIN
    UPDATE
      Scorer
    SET 
      Score = @Score
    WHERE
      ScorerID = @ScorerID

    RETURN @ScorerID
  END
  ELSE
  BEGIN
    INSERT 
      Scorer 
      (ScorerID, Score, DateCreated)
    VALUES
      (@ScorerID, @Score, GETDATE())

    RETURN SCOPE_IDENTITY()
  END
END

절차의 반환 값을 사용하여 새로운 스코어리드를 잡으십시오.

SqlCommand UpdateScorer = New SqlCommand("InsertOrUpdateScorer", DbConn);
UpdateScorer.CommandType = CommandType.StoredProcedure;

SqlParameter RetValue = UpdateScorer.Parameters.Add("RetValue", SqlDbType.Int);
RetValue.Direction = ParameterDirection.ReturnValue;

SqlParameter Score = UpdateScorer.Parameters.Add("@Score", SqlDbType.Int);
Score.Direction = ParameterDirection.Input;

SqlParameter ScorerId = UpdateScorer.Parameters.Add("@ScorerID", SqlDbType.Int);
ScorerId.Direction = ParameterDirection.Input;

Score.Value = 15;    // whatever
ScorerId.Value = 15; // whatever

UpdateScorer.ExecuteNonQuery();
Console.WriteLine(RetValue.Value);

한 번에 모든 값을 업데이트하거나 삽입하려는 경우, 한 레코드뿐만 아니라이 스 니펫을 사용했습니다.

첫 번째 업데이트 스크립트를 실행하십시오

UPDATE Table1 
SET OPIS = T1.OPIS
FROM
    Table1 AS T
INNER JOIN
    Table2 AS T1
    ON
        T.col = T1.col;

그런 다음 삽입 스크립트를 수행하십시오

INSERT INTO Table1 
SELECT * FROM 
    (
        SELECT T1.* Table2 AS T1
        LEFT JOIN Table1 AS T2 ON (T2.col = T1.col)
        WHERE T2.col IS NULL
    ) AS T;

누군가가 이것이 유용하다는 것을 알기를 바랍니다.

MySQL (경우에 따라)에서 이것의 동등한 것은 다음과 같습니다.

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

누군가는 이것이 기사와 관련이 있음을 발견 할 수 있습니다. SQL Server의 삽입 또는 업데이트 솔루션

업데이트 된 버전 사용 병합 (Transact-SQL):

DECLARE @USER_ID AS INT=76;
DECLARE @TYPE AS NVARCHAR(MAX)='set.global';
DECLARE @FKEY AS NVARCHAR(MAX)='21';
DECLARE @DATA AS NVARCHAR(MAX)='test';

        begin tran
            MERGE UserData
            USING (SELECT @USER_ID, @TYPE, @FKEY, @DATA) AS Source([UserId], [Type], [FKey], [Data])
            ON (UserData.[UserId] = Source.[UserId] AND UserData.[Type] = Source.[Type] AND (UserData.[FKey] = Source.[FKey] OR (Source.[FKey] IS NULL AND UserData.[FKey] IS NULL)))
            WHEN MATCHED
            THEN
                UPDATE SET [Data] = Source.[Data]
            WHEN NOT MATCHED BY TARGET THEN
                INSERT 
                           ([UserId]
                           ,[Type]
                           ,[FKey]
                           ,[Data])
                     VALUES
                           ( Source.[UserId]
                           ,Source.[Type]
                           ,Source.[FKey]
                           ,Source.[Data]);

        commit tran
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top