我需要使用以下字段更新数据库中的记录
[ID] int (AutoIncr. PK)
[ScorerID] int
[Score] int
[DateCreated] smalldatetime
如果今天的日期存在记录(只应检查日期部分,而不是时间)和给定的记分员,我想更新这个人和今天的分数值。如果得分手今天没有记录,我想创建一个新记录。
我正在试图弄清楚如何把它变成单个(这可能吗?)sql语句。顺便说一句,我正在使用MSSQl数据库和ExecuteNonQuery()
方法来发出查询。
答案 0 :(得分:16)
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
答案 1 :(得分:3)
其他人已经涵盖了2005(和之前)兼容的T-SQL / apprroaches。我只想补充一点,如果你有幸使用SQL Server 2008,你可以利用新的Merge(有时称为Upsert)语句。
我很难找到可以进一步解释的博客文章或文章,但我确实发现了(1) helpful entry。官方MSDN条目为(2) here.
(1)[http://www.sqlservercurry.com/2008/05/sql-server-2008-merge-statement.html]
(2)[http://msdn.microsoft.com/en-us/library/bb510625.aspx]
答案 2 :(得分:1)
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);
答案 3 :(得分:1)
对于需要一次更新或插入所有值的情况,不仅仅是我使用此代码段的一条记录
首先运行更新脚本</ p>
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;
有人可以发现这与Solutions for INSERT OR UPDATE on SQL Server
上的文章有关使用MERGE (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