SQL حدد: Update إذا موجودا، أدخل إن لم يكن - مع مقارنة تاريخ جزء؟
-
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