SQL حدد: Update إذا موجودا، أدخل إن لم يكن - مع مقارنة تاريخ جزء؟

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 / apprroaches. أنا فقط أريد أن أضيف أنه إذا كنت محظوظا بما فيه الكفاية للعمل مع SQL Server 2008 أو هل يمكن الاستفادة من دمج الجديد (يشار إليها أحيانا باسم Upsert) بيان.

وكان لي صعوبة في العثور على دخول بلوق أو المادة وهو ما يفسر أكثر من ذلك، ولكن لم أجد هذا بدلا <لأ href = "http://www.sqlservercurry.com/2008/05/sql-server-2008-merge- statement.html "يختلط =" نوفولو noreferrer "> (1) دخول مفيدة . دخول MSDN الرسمي (2) هنا.

(1) [ HTTP: // www.sqlservercurry.com/2008/05/sql-server-2008-merge-statement.html]
(2) [ http://msdn.microsoft.com/ أون لنا / مكتبة / 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

استخدم قيمة الإرجاع من الإجراء للاستيلاء على ScorerId جديدة.

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);

لحالة عند الرغبة في تحديث أو إدراج جميع القيم في آن واحد، وليس فقط لسجل واحد أنا استخدم هذا المقتطف

1 تشغيل البرنامج النصي التحديث

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;

ونأمل أن شخص ما أن هذه مفيدة.

وما يعادل هذا في الخلية (في بعض الحالات) هو شيء من هذا القبيل:

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

وشخص ما يمكن أن وجد أن لهذا علاقة هذه المادة في حلول ل INSERT أو UPDATE على SQL Server

وتحديث نسخة باستخدام دمج (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